Skip to Content

body_classes()

Adds useful information to the body tag as classes.

PHP July 9, 2018

Usage

This function runs automatically, so it is not called manually. Is this incorrect?

Additional Notes

Regarding the dynamic time-based classes, refer to this graphic:

Source File

Located in /libs/Functions.php on line 2785.

No Hooks

This function does not have any filters or actions available. Request one?
PHP
        public function body_classes($classes){
            if ( !$this->is_admin_page() ){
                $this->timer('Nebula Body Classes');

                $spaces_and_dots = array(' ', '.');
                $underscores_and_hyphens = array('_', '-');

                //Check the Save Data header
                $classes[] = ( $this->is_save_data() )? 'save-data' : '';

                //Device
                $classes[] = strtolower($this->get_device('formfactor')); //Form factor (desktop, tablet, mobile)
                $classes[] = strtolower($this->get_device('full')); //Device make and model
                $classes[] = strtolower(str_replace($spaces_and_dots, $underscores_and_hyphens, $this->get_os('full'))); //Operating System name with version
                $classes[] = strtolower(str_replace($spaces_and_dots, $underscores_and_hyphens, $this->get_os('name'))); //Operating System name
                $classes[] = strtolower(str_replace($spaces_and_dots, $underscores_and_hyphens, $this->get_browser('full'))); //Browser name and version
                $classes[] = strtolower(str_replace($spaces_and_dots, $underscores_and_hyphens, $this->get_browser('name'))); //Browser name
                $classes[] = strtolower(str_replace($spaces_and_dots, $underscores_and_hyphens, $this->get_browser('engine'))); //Rendering engine

                //Browser language
                $classes[] = 'lang-' . strtolower(get_bloginfo('language'));
                if ( is_rtl() ){
                    $classes[] = 'lang-dir-rtl';
                }

                //When installed to the homescreen, Chrome is detected as "Chrome Mobile". Supplement it with a "chrome" class.
                if ( $this->get_browser('name') === 'Chrome Mobile' ){
                    $classes[] = 'chrome';
                }

                //Alternate Bootstrap versions
                $classes[] = 'bs-' . $this->get_option('bootstrap_version');

                //User Information
                $current_user = wp_get_current_user();
                if ( is_user_logged_in() ){
                    $classes[] = 'user-logged-in';
                    $classes[] = 'user-' . $current_user->user_login;

                    $user_info = get_userdata(get_current_user_id());
                    if ( !empty($user_info->roles) ){
                        $classes[] = 'user-role-' . $user_info->roles[0];
                    } else {
                        $classes[] = 'user-role-unknown';
                    }
                } else {
                    $classes[] = 'user-not-logged-in';
                }

                //Staff
                if ( $this->is_staff() ){
                    $classes[] = 'is-staff';
                    if ( $this->is_dev() ){
                        $classes[] = 'staff-developer';
                    } elseif ( $this->is_client() ){
                        $classes[] = 'staff-client';
                    }
                }

                //Post Information
                if ( !is_search() && !is_archive() && !is_front_page() && !is_404() ){
                    global $post;
                    if ( isset($post) ){
                        $segments = explode('/', trim(parse_url($this->super->server['REQUEST_URI'], PHP_URL_PATH), '/'));
                        $parents = get_post_ancestors($post->ID);
                        foreach ( $parents as $parent ){
                            if ( !empty($parent) ){
                                $classes[] = 'ancestor-id-' . $parent;
                            }
                        }

                        foreach ( $segments as $segment ){
                            if ( !empty($segment) ){
                                $classes[] = 'ancestor-of-' . $segment;
                            }
                        }

                        foreach ( get_the_category($post->ID) as $category ){
                            $classes[] = 'cat-id-' . $category->cat_ID;
                            $classes[] = 'cat-' . $category->slug;
                        }
                    }
                }

                //Singular
                if ( is_singular() ){
                    $classes[] = 'singular';
                } else {
                    $classes[] = 'hfeed'; //Adds `hfeed` to non singular pages.
                }

                //Customizer
                if ( is_customize_preview() ){
                    $classes[] = 'customizer-preview';
                }

                //Front Page
                if ( is_front_page() ){
                    $classes[] = 'front-page';

                    //Homepage Hero (Customizer)
                    if ( !get_theme_mod('nebula_hero', true) ){
                        $classes[] = 'no-hero';
                    }
                }

                $nebula_theme_info = wp_get_theme();
                $classes[] = 'nebula';
                $classes[] = 'nebula_' . str_replace('.', '-', $this->version('primary'));

                //Time of Day
                if ( $this->has_business_hours() ){
                    $classes[] = ( $this->business_open() )? 'business-open' : 'business-closed';
                }

                $relative_time = $this->relative_time('description');
                foreach( $relative_time as $relative_desc ){
                    $classes[] = 'time-' . $relative_desc;
                }
                if ( date('H') >= 12 ){
                    $classes[] = 'time-pm';
                } else {
                    $classes[] = 'time-am';
                }

                if ( $this->get_option('latitude') && $this->get_option('longitude') ){
                    $lat = floatval($this->get_option('latitude'));
                    $lng = floatval($this->get_option('longitude'));
                    $gmt = intval(get_option('gmt_offset'));
                    $zenith = 90+50/60; //Civil twilight = 96°, Nautical twilight = 102°, Astronomical twilight = 108°
                    global $sunrise, $sunset;
                    $sunrise = strtotime(date_sunrise(strtotime('today'), SUNFUNCS_RET_STRING, $lat, $lng, $zenith, $gmt));
                    $sunset = strtotime(date_sunset(strtotime('today'), SUNFUNCS_RET_STRING, $lat, $lng, $zenith, $gmt));
                    $length_of_daylight = $sunset-$sunrise;
                    $length_of_darkness = DAY_IN_SECONDS-$length_of_daylight;

                    if ( time() >= $sunrise && time() <= $sunset ){
                        $classes[] = 'time-daylight';
                        if ( strtotime('now') < $sunrise+($length_of_daylight/2) ){
                            $classes[] = 'time-waxing-gibbous'; //Before solar noon
                            $classes[] = ( strtotime('now') < ($length_of_daylight/4)+$sunrise )? 'time-narrow' : 'time-wide';
                        } else {
                            $classes[] = 'time-waning-gibbous'; //After solar noon
                            $classes[] = ( strtotime('now') < ((3*$sunset)+$sunrise)/4 )? 'time-wide' : 'time-narrow';
                        }
                    } else {
                        $classes[] = 'time-darkness';
                        $previous_sunset_modifier = ( date('H') < 12 )? DAY_IN_SECONDS : 0; //Times are in UTC, so if it is after actual midnight (before noon) we need to use the sunset minus 1 day in formulas
                        $solar_midnight = (($sunset-$previous_sunset_modifier)+($length_of_darkness/2)); //Calculate the appropriate solar midnight (either yesterday's or tomorrow's) [see above]
                        if ( strtotime('now') < $solar_midnight ){
                            $classes[] = 'time-waning-crescent'; //Before solar midnight
                            $classes[] = ( strtotime('now') < ($length_of_darkness/4)+($sunset-$previous_sunset_modifier) )? 'time-wide' : 'time-narrow';
                        } else {
                            $classes[] = 'time-waxing-crescent'; //After solar midnight
                            $classes[] = ( strtotime('now') < ($sunrise+$solar_midnight)/2 )? 'time-narrow' : 'time-wide';
                        }
                    }

                    $sunrise_sunset_length = 35; //Length of sunrise/sunset in minutes.
                    if ( strtotime('now') >= $sunrise-(60*$sunrise_sunset_length) && strtotime('now') <= $sunrise+(60*$sunrise_sunset_length) ){ //X minutes before and after true sunrise
                        $classes[] = 'time-sunrise';
                    }
                    if ( strtotime('now') >= $sunset-(60*$sunrise_sunset_length) && strtotime('now') <= $sunset+(60*$sunrise_sunset_length) ){ //X minutes before and after true sunset
                        $classes[] = 'time-sunset';
                    }
                }

                $classes[] = 'date-day-' . strtolower(date('l'));
                $classes[] = 'date-ymd-' . strtolower(date('Y-m-d'));
                $classes[] = 'date-month-' . strtolower(date('F'));

                $this->timer('Nebula Body Classes', 'end');
            }

            return $classes;
        }

Override

This function can not be short-circuited with an override filter. Request one?