Skip to Content
Menu

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:

Was this page helpful? Yes No


    A feedback message is required to submit this form.


    Please check that you have entered a valid email address.

    Enter your email address if you would like a response.

    Thank you for your feedback!

    Source File

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

    2 Hooks

    Find these filters and actions in the source code below to hook into them. Use do_action() and add_filter() in your functions file or plugin.

    Filters
    This function has no filter hooks available. Request one?

    Actions
    "qm/info"
    "qm/info"
    Need a new action hook? Request one here.

    PHP
            public function body_classes($classes){
                if ( !$this->is_admin_page() ){
                    $this->timer('Nebula Body Classes', 'start', '[Nebula] Markup');
    
                    $spaces_and_dots = array(' ', '.');
                    $underscores_and_hyphens = array('_', '-');
    
                    //Check the Save Data header
                    if ( $this->is_save_data() ){
                        $classes[] = '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
    
                    if ( $this->is_bot() ){
                        $classes[] = 'bot bot-visitor device-bot';
                    }
    
                    //Website language
                    $classes[] = 'lang-blog-' . strtolower(get_bloginfo('language'));
                    if ( is_rtl() ){
                        $classes[] = 'lang-dir-rtl';
                    }
    
                    //Preferred browser language
                    if ( !empty($this->super->server['HTTP_ACCEPT_LANGUAGE']) ){
                        $classes[] = sanitize_html_class('lang-user-' . strtolower(explode(",", $this->super->server['HTTP_ACCEPT_LANGUAGE'])[0])); //Example: fr-fr,en-us;q=0.7,en;q=0.3
                    }
    
                    //Geo data if available
                    if ( !empty($this->get_geo_data('country')) ){
                        $classes[] = sanitize_html_class('country-' . strtolower($this->get_geo_data('country')));
                        do_action('qm/info', 'Geo Country: ' . $this->get_geo_data('country'));
                    }
                    if ( !empty($this->get_geo_data('region')) ){
                        $classes[] = sanitize_html_class('region-' . str_replace(' ', '-', strtolower($this->get_geo_data('region'))));
                        do_action('qm/info', 'Geo Region: ' . $this->get_geo_data('region'));
                    }
    
                    //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';
                    }
    
                    //User Information
                    $current_user = wp_get_current_user();
                    if ( is_user_logged_in() ){
                        $classes[] = 'user-logged-in';
                        $classes[] = sanitize_html_class('user-' . $current_user->user_login);
    
                        $user_info = get_userdata(get_current_user_id());
                        if ( !empty($user_info->roles) ){
                            $classes[] = sanitize_html_class('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) ){
                            $parents = get_post_ancestors($post->ID);
                            foreach ( $parents as $parent ){
                                if ( !empty($parent) ){
                                    $classes[] = 'ancestor-id-' . $parent;
                                }
                            }
    
                            $segments = explode('/', trim(parse_url($this->super->server['REQUEST_URI'], PHP_URL_PATH), '/'));
                            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.
                    }
    
                    //Give each page a unique class
                    if ( is_page() ){
                        $classes[] = 'page-' . basename(get_permalink());
                    }
    
                    //If this post has a featured image
                    if ( has_post_thumbnail() ){
                        $classes[] = 'has-featured-image';
                    }
    
                    //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[] = sanitize_html_class('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') ){
                        $latitude = floatval($this->get_option('latitude'));
                        $longitude = floatval($this->get_option('longitude'));
    
                        $suninfo = date_sun_info(strtotime('today'), $latitude, $longitude); //Civil twilight = 96deg, Nautical twilight = 102deg, Astronomical twilight = 108deg - these are already accounted for in this PHP function
    
                        $sunrise = $suninfo['sunrise']; //The timestamp of the sunrise (zenith angle = 90deg 35min)
                        $sunset  = $suninfo['sunset']; //The timestamp of the sunset (zenith angle = 90deg 35min)
    
                        $length_of_daylight = $sunset-$sunrise;
                        $length_of_darkness = DAY_IN_SECONDS-$length_of_daylight;
    
                        $now = strtotime('now'); //Current time
    
                        if ( time() >= $sunrise && time() <= $sunset ){
                            $classes[] = 'time-daylight';
                            if ( $now < $sunrise+($length_of_daylight/2) ){
                                $classes[] = 'time-waxing-gibbous'; //Before solar noon
                                $classes[] = ( $now < ($length_of_daylight/4)+$sunrise )? 'time-narrow' : 'time-wide';
                            } else {
                                $classes[] = 'time-waning-gibbous'; //After solar noon
                                $classes[] = ( $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 ( $now < $solar_midnight ){
                                $classes[] = 'time-waning-crescent'; //Before solar midnight
                                $classes[] = ( $now < ($length_of_darkness/4)+($sunset-$previous_sunset_modifier) )? 'time-wide' : 'time-narrow';
                            } else {
                                $classes[] = 'time-waxing-crescent'; //After solar midnight
                                $classes[] = ( $now < ($sunrise+$solar_midnight)/2 )? 'time-narrow' : 'time-wide';
                            }
                        }
    
                        $sunrise_sunset_length = 35; //Length of sunrise/sunset in minutes.
                        if ( $now >= $sunrise-(60*$sunrise_sunset_length) && $now <= $sunrise+(60*$sunrise_sunset_length) ){ //X minutes before and after true sunrise
                            $classes[] = 'time-sunrise';
                        }
                        if ( $now >= $sunset-(60*$sunrise_sunset_length) && $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'));
    
                    $classes = array_values(array_unique(array_filter($classes))); //De-dupe and clean up the classes array
    
                    $this->timer('Nebula Body Classes', 'end');
                }
    
                return $classes;
            }
    

    Override

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