Add post classes for custom taxonomies to custom post type?

I was surprised to learn that custom taxonomies aren’t added as body or post classes like categories and tags are.

I’m sure this will be added in a future version of WordPress, but in the meantime I need to add a custom taxonomy to the post class so that I can style post in a certain category in that taxonomy differently.

Read More

It’d be most elegant to filter the post class and add the taxonomies to it. I found a snippet to pull off a similar trick with the body class, but I haven’t been successful in adapting it:

function wpprogrammer_post_name_in_body_class( $classes ){
 if( is_singular() )
 {
  global $post;
  array_push( $classes, "{$post->post_type}-{$post->post_name}" );
 }
 return $classes;
}

add_filter( 'body_class', 'wpprogrammer_post_name_in_body_class' );

A bit more crudely, I thought about using the_terms function to create my own classes for the custom posts, something like this:

<div class="<?php the_terms( $post->ID, 'taxonomy', '', ' ', '' ); ?>"></div>

But then I’d have to filter out the HTML that the_term generates.

Am I missing anything obvious here, is there a simpler way to solve this issue?

Related posts

Leave a Reply

5 comments

  1. I found a snippet of code courtesy of mfields that solved this problem for me, here’s what I ended up using:

    <?php   // Add custom taxonomies to the post class
    
        add_filter( 'post_class', 'custom_taxonomy_post_class', 10, 3 );
    
        if( !function_exists( 'custom_taxonomy_post_class' ) ) {
    
            function custom_taxonomy_post_class( $classes, $class, $ID ) {
    
                $taxonomy = 'listing-category';
    
                $terms = get_the_terms( (int) $ID, $taxonomy );
    
                if( !empty( $terms ) ) {
    
                    foreach( (array) $terms as $order => $term ) {
    
                        if( !in_array( $term->slug, $classes ) ) {
    
                            $classes[] = $term->slug;
    
                        }
    
                    }
    
                }
    
                return $classes;
    
            }
    
        }  ?>
    
  2. Update: As of WordPress 4.2-alpha-31271 (23 January 2015), CSS classes for custom taxonomy terms are now automatically added by WordPress core when using get_post_class().

    The following code snippet is no longer necessary.


    Here’s a good utility function that will add all registered, public taxonomy terms to the post_class() for use as CSS hooks in themes:

    /**
    * Add Custom Taxonomy Terms To The Post Class
    */
    
    add_filter( 'post_class', 'wpse_2266_custom_taxonomy_post_class', 10, 3 );
    
    if ( ! function_exists('wpse_2266_custom_taxonomy_post_class') ) {
        function wpse_2266_custom_taxonomy_post_class($classes, $class, $ID) {
    
            $taxonomies_args = array(
                'public' => true,
                '_builtin' => false,
            );
    
            $taxonomies = get_taxonomies( $taxonomies_args, 'names', 'and' );
    
            $terms = get_the_terms( (int) $ID, (array) $taxonomies );
    
            if ( ! empty( $terms ) ) {
                foreach ( (array) $terms as $order => $term ) {
                    if ( ! in_array( $term->slug, $classes ) ) {
                        $classes[] = $term->slug;
                    }
                }
            }
    
            $classes[] = 'clearfix';
    
            return $classes;
        }
    }
    

    Inspiration and credit from Jan Fabry’s previous answer.

    Put the above code in your theme’s functions.php file. Then, whenever the post_class() is used in a template:

    <article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
    

    It will output any public custom taxonomy term(s) attached to the post, in addition to all of the default post classes. For example:

    <article id="post-247" class="post-247 post-type ... status-publish hentry clearfix">
    

    It handily works with Custom Post Types and Taxonomies.

  3. I have an improvement on @rjb’s answer (I don’t have enough reputation to comment, sorry). I was getting an “array to strings conversion” error with debug mode turned on, so I did a foreach loop of the returned taxonomies and now there’s no error.

    Hope this helps someone!

    add_filter( 'post_class', 'custom_taxonomy_post_class', 10, 3 );
    
    function custom_taxonomy_post_class($classes, $class, $ID) {
    
        $taxonomies_args = array(
            'public' => true,
            '_builtin' => false,
        );
    
        $taxonomies = get_taxonomies( $taxonomies_args, 'names', 'and' );
    
        foreach ($taxonomies as $taxonomy) {
    
        $terms = get_the_terms( (int) $ID, $taxonomy );
    
        if ( ! empty( $terms ) ) {
            foreach ( (array) $terms as $order => $term ) {
                if ( ! in_array( $term->slug, $classes ) ) {
                    $classes[] = $term->slug;
                }
            }
        }
    
    
    }
    
        $classes[] = 'clearfix';
    
        return $classes;
    }
    
  4. Instead of the_terms, you could use get_the_terms, which will return the taxonomy term objects. The Codex has documentation for the tag-only version, get_the_tags.

    That would give you something like this:

    function wpprogrammer_custom_taxonomy_in_body_class( $classes ){
      if( is_singular() )
      {
        $custom_terms = get_the_terms(0, 'my_custom_taxonomy');
        if ($custom_terms) {
          foreach ($custom_terms as $custom_term) {
            $classes[] = 'custom_tag_' . $custom_term->slug;
          }
        }
      }
      return $classes;
    }
    
    add_filter( 'body_class', 'wpprogrammer_custom_taxonomy_in_body_class' );