Display custom post type taxonomy in a WordPress excerpt for current post

The question:

Hi there and thanks in advance for any help. I am trying to display custom taxonomies(Themes and Guests)on the current post (of custom post type, Podcasts). I have tried the code below, but I am getting an empty result ie. nothing is showing. I added $post->ID after I realised that the code was working fine, but was displaying ALL categories, not just the ones for the current post.

    add_filter( 'the_excerpt', function( $excerpt ) {

        $themes = get_terms($post->ID,'themes',
            array(
                'hide_empty' => false,
                'orderby'    => 'name',
                'order'      => 'ASC'
            )
        );?> 
         <p><?php
        foreach( $themes as $theme ):
            ?>    
           <span class="theme"><?php echo $theme->name; ?></span>
        <?php endforeach;?></p><?php
         $guests = get_terms($post->ID,'guests',
            array(
                'hide_empty' => false,
                'orderby'    => 'name',
                'order'      => 'ASC'
            )
        );?> 
         <div class="guest-wrap"><span class="guest-label">Episode Guests: </span>
        <?php
        
        foreach($guests as $guest ):
            ?>  
           <span class="guests"><?php echo $guest->name; ?></span>
        <?php endforeach;?></div><?php
    $player = get_post_meta( get_the_ID(), 'embed_episode_code', true );
    return $player . $excerpt;
} );

The Solutions:

Below are the methods you can try. The first solution is probably the best. Try others if the first one doesn’t work. Senior developers aren’t just copying/pasting – they read the methods carefully & apply them wisely to each case.

Method 1

In the scope of the code presented, $post is not defined. In order to use the $post global, you need to declare it as global beforehand (usually at the top of the function body which utilizes it):

global $post;

$id = $post->ID;

That said, directly interacting with globals is generally discouraged as you’re often accessing WordPress’s raw state data, quite possibly circumventing important hooks or logic. Where possible, use the interfaces which WordPress provides to access this data instead:

$id = get_the_ID();

Check out the documentation for the get_terms() function – it only takes a single argument, and queries for terms globally without regard to a post ID. I think you’ve intended those calls to use the wp_get_post_terms() function instead.

If this filter is intended to only alter excerpts for podcast post-types, you should check the post type before modifying the excerpt as well.

WordPress’s filters are intended to take in a value as an argument and return a modified or unaltered version of it – printing output within a filter is generally a bad idea, and may lead to unexpected errors or behaviors. Composing markup in big strings can be pretty annoying though, but there’s a convenient solution in capturing output in an “output buffer” and then dumping the contents of that buffer to a string.

All of the above in mind, I might rewrite this filter as such:

add_filter( 'the_excerpt', function( $excerpt ) {
  if( get_post_type() !== 'podcast' )
    return $excerpt;
  
  $themes = wp_get_post_terms(
    get_the_ID(),
    'themes',
     array(
       'hide_empty' => false,
       'orderby'    => 'name',
       'order'      => 'ASC'
     )
   );

   $guests = wp_get_post_terms(
     get_the_ID(),
     'guests',
     array(
       'hide_empty' => false,
       'orderby'    => 'name',
       'order'      => 'ASC'
     )
   );

   ob_start();
  ?> 
    <p>
    <?php foreach( $themes as $theme ): ?>    
      <span class="theme"><?php echo $theme->name; ?></span>
    <?php endforeach;?>
    </p>
    <div class="guest-wrap"><span class="guest-label">Episode Guests: </span>
    <?php foreach($guests as $guest ): ?>  
      <span class="guests"><?php echo $guest->name; ?></span>
    <?php endforeach; ?>
    </div>
  <?php

  $term_markup = ob_get_clean();
  $player      = get_post_meta( get_the_ID(), 'embed_episode_code', true );
   
  return $term_markup . $player . $excerpt;
} );


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Comment