-
-
Save hearvox/138586b3741b012c2e9378421f4fb209 to your computer and use it in GitHub Desktop.
| <?php | |
| /** | |
| * Insert class into body tag for highest level Category or Page. | |
| * | |
| * Pages and Categories with identical slugs get the same class. | |
| * Works on Pages, Posts, and Category achives. | |
| * | |
| * @return string $top_slug Class name for body tag. | |
| */ | |
| function top_cat_or_page_body_class( $class ) { | |
| $prefix = 'topic-'; // Editable class name prefix. | |
| global $wp_query; | |
| $object_id = $wp_query->get_queried_object_id(); | |
| $top_slug = ( is_home() ) ? 'home' : 'default'; | |
| if ( is_single() ) { | |
| $cats = get_the_category( $object_id ); // Get post categories. | |
| $parents = get_ancestors( $cats[0]->term_id, 'category', 'taxonomy' ); | |
| $top_id = ( $parents ) ? end( $parents ) : $object_id; | |
| // If term has parents, get ID of top page. | |
| $top_cat = get_category( $top_id ); // Get top cat object. | |
| $top_slug = $top_cat->slug; // Get top cat slug. | |
| } | |
| if ( is_category() ) { | |
| $parents = get_ancestors( $object_id, 'category', 'taxonomy' ); | |
| $top_id = ( $parents ) ? end( $parents ) : $object_id; | |
| // If cat has parents, get ID of top cat. | |
| $top_cat = get_category( $top_id ); // Get top cat object. | |
| $top_slug = $top_cat->slug; // Get top cat slug. | |
| } | |
| if ( is_page() ) { | |
| $parents = get_ancestors( $object_id, 'page', 'post_type' ); | |
| $top_id = ( $parents ) ? end( $parents ) : $object_id; | |
| // If page has parents, get ID of top page. | |
| $top_page = get_post( $top_id ); // Get top page object. | |
| $top_slug = $top_page->post_name; // Get top page slug. | |
| } | |
| $class[] = $prefix . $top_slug; | |
| return $class; | |
| } | |
| add_filter( 'body_class', 'top_cat_or_page_body_class' ); | |
| /* | |
| // Rewrote the above in 2021. Below is the legacy function: | |
| // Add body-class for top-level parent Page or Category | |
| function topcatpg_body_class( $class ) { | |
| $prefix = 'topic-'; // Editable class name prefix. | |
| $top_cat_pg = 'home'; // Default. | |
| global $top_cat_pg; | |
| // Get class name from top-level Category or Page. | |
| global $wp_query; | |
| if ( is_single() ) { | |
| $wp_query->post = $wp_query->posts[0]; | |
| setup_postdata( $wp_query->post ); | |
| // Climb Posts category hierarchy, successively replacing | |
| // class name top_cat_pg with slug of higher level cat. | |
| foreach( (array) get_the_category() as $cat ) { | |
| if ( !empty( $cat->slug ) ) | |
| $top_cat_pg = sanitize_html_class( $cat->slug, $cat->cat_ID ); | |
| while ( $cat->parent ) { | |
| $cat = get_category( (int) $cat->parent); | |
| if ( !empty( $cat->slug ) ) | |
| $top_cat_pg = sanitize_html_class( $cat->slug, $cat->cat_ID ); | |
| } | |
| } | |
| } elseif ( is_archive() ) { | |
| if ( is_category() ) { | |
| $cat = $wp_query->get_queried_object(); | |
| $top_cat_pg = $cat->slug; | |
| // Climb Category hierarchy, successively replacing | |
| // class name with slug of higher level cat. | |
| while ( $cat->parent ) { | |
| $cat = get_category( (int) $cat->parent ); | |
| if ( !empty( $cat->slug ) ) | |
| $top_cat_pg = sanitize_html_class( $cat->slug, $cat->cat_ID ); | |
| } | |
| } | |
| } elseif ( is_page() ) { | |
| global $post; | |
| if ( $post->post_parent ) { | |
| $ancestors = get_post_ancestors( $post->ID ); | |
| $root = count( $ancestors ) - 1; | |
| $top_id = $ancestors[$root]; | |
| $top_pg = get_page( $top_id ); | |
| $top_cat_pg = $top_pg->post_name; | |
| } else { | |
| $top_cat_pg = $post->post_name; | |
| } | |
| } | |
| $class[] = $prefix . $top_cat_pg; | |
| return $class; | |
| } | |
| // Uncomment to use this function instead ot the above newer one: | |
| // add_filter( 'body_class', 'topcatpg_body_class' ); | |
| */ | |
| ?> |
This code works SO well, and I really want to keep using it, but I seem to be getting daily errors in my php_errorlog:
[20-Feb-2023 20:17:03 UTC] PHP Warning: Attempt to read property "slug" on null in /home/customer/www/[website folder]/public_html/wp-content/themes/generatepress_child/functions.php on line 91
It's referring to the first instance of $top_slug = $top_cat->slug; // Get top cat slug.
Is there something I can do prevent the errors? The code is working perfectly otherwise!
@sambieluy
None of the sites I work with are using this script now. So I'm just guessing, not testing, but maybe I need to wrap that error-producing line in an if, to trap for get_category( $top_id ) not returning a category (because, if it did, the cat would have a slug), like:
$top_slug = ($top_cat) ? $top_cat->slug : $top_slug;
If you have a chance to test that, please do. Tell me if it gets rid of the errors.
Thanks so much for your response, @hearvox :)
I tried changing $top_slug = $top_cat->slug to if ( $top_slug = $top_cat->slug ); yesterday (Feb. 21st), and it seems like 3 more of the same errors came through today. Interestingly, there are way fewer errors this time, but I'm not sure if that's relevant.
[22-Feb-2023 16:42:41 UTC] PHP Warning: Attempt to read property "slug" on null in /home/customer/www/[website folder]/public_html/wp-content/themes/generatepress_child/functions.php on line 91
[22-Feb-2023 16:45:23 UTC] PHP Warning: Attempt to read property "slug" on null in /home/customer/www/[website folder]/public_html/wp-content/themes/generatepress_child/functions.php on line 91
[22-Feb-2023 18:40:26 UTC] PHP Warning: Attempt to read property "slug" on null in /home/customer/www/[website folder]/public_html/wp-content/themes/generatepress_child/functions.php on line 91
Could it be because I implemented the "if" statement incorrectly (screenshot attached for more context)? Do I need to have some kind of dependent condition afterwards? Really sorry for my lack of knowledge with PHP!
@hearvox Just a quick update that we're back to the same number of "Attempt to read property 'slug' on null" errors today (16 instances so far today), so ignore what I said about there being fewer errors. It must be based on how many users cause the code to run.

Thank you! I really appreciate you responding so quickly. And I appreciate you sharing the script.
Now I just have to remember exactly what this script was doing on my site in the first place. :-)