Search code examples
wordpresscustom-post-typetaxonomy-terms

Adding taxonomy term to single CPT pages removes body classes from regular pages


I wanted to add the taxonomy term for single CPT pages so I did that by using the code below:

//* Add CPT taxonomy terms to body class
function add_taxonomy_to_single( $classes ) {
  if ( is_single() ) {
    global $post;
    $my_terms = get_the_terms( $post->ID, 'skill' );
    if ( $my_terms && ! is_wp_error( $my_terms ) ) {
      foreach ($my_terms as $term) {
        $classes[] = $term->slug;
      }
    }
    return $classes;
  }
}
add_filter( 'body_class', 'add_taxonomy_to_single' );

It worked fine for the intended single CPT pages as shown below. "selected-works" is the taxonomy term.

<body data-rsssl="1" class="project-template-default single single-project postid-4829 logged-in woocommerce-js selected-works chrome">

But, unfortunately, it also affected the regular pages (that weren't single). For the regular pages, it removed all of the classes from body.

<body data-rsssl="1" class="chrome">

How can I alter the code so it only affects the single CPT pages and no other pages?


Solution

  • Adding an answer from my comment:

    You need to move the return $classes out of the if statement:

    //* Add CPT taxonomy terms to body class
    function add_taxonomy_to_single( $classes ) {
      if ( is_single() ) {
        global $post;
        $my_terms = get_the_terms( $post->ID, 'skill' );
        if ( $my_terms && ! is_wp_error( $my_terms ) ) {
          foreach ($my_terms as $term) {
            $classes[] = $term->slug;
          }
        }
      }
    
    return $classes;
    
    }
    add_filter( 'body_class', 'add_taxonomy_to_single' );
    

    The reason is that the body_class filter hook gets run on page load, so when you are passing in $classes to your filter function, if the if statement isn't satisfied, unless the return is outside of the if, the $classes argument never gets returned to the original filter.