So I made a couple of custom taxonomies to add multiple categories to a page/project. (single-work.php) The default one (built in category) being project type, and the two new ones being client and agency.

Basically I use the same code for all three, but I just noticed that what it's doing for the two custom categories is basically reading out EVERY tag I've added to different projects, instead of only showing the tag that's selected for that specific page.

In other words, it's basically just showing every tag that can be found under the "Choose from the most used tags" area. Despite only a single tag being selected for each project.

I hope that was somewhat clear :)

Here's the code I'm using:

<?php $terms = get_terms( 'portfolio_tags_client' );
    foreach ( $terms as $term ) {
        $term_link = get_term_link( $term );
        if ( is_wp_error( $term_link ) ) {
    echo 'Client: <a href="' . esc_url( $term_link ) . '">' . $term->name . '</a>&nbsp;<br />';

And here's the taxonomy it's coming out of, if that helps:

    'portfolio_tags_client',  //The name of the taxonomy. Name should be in slug form (must not contain capital letters or spaces). 
    'work', // Post type name
        'hierarchical'  =>  false,
        'label'         =>  'Clients', // Display name
        'singular_name' =>  'Client',
        'query_var'     =>  true,
        'rewrite'       =>  array(
        'slug'          =>  'client', // This controls the base slug that will display before each term
        'with_front'    =>  false // Don't display the category base before 

Does anyone know what it could be? I've spent way more time than I'd like to admit trying to fix this :)

UPDATE Fixed! Thanks so much for the help guys. I really appreciate it. Here's the final code:

<?php $post_tags = get_the_terms(get_the_ID(), 'portfolio_tags_client'); 
    if ($post_tags) {
        foreach($post_tags as $tag) {
        echo 'Client: <a href="'.get_tag_link($tag->term_id).'" title="'.$tag->name.'">'. $tag->name .'</a>&nbsp;<br />';

2 Answers 2


What you are looking for is get_the_terms(). You can get custom terms for the current post by using the following code:

$post_tags = get_the_terms(get_the_ID(), 'portfolio_tags_client'); 
if ($post_tags) { ?>
    <div class="tags-div">
        <h3><?php _e( 'Tags', 'text-domain' ); ?></h3>  
        <div class="post-tags"><?php
            foreach($post_tags as $tag) {
                echo '<a href="'.get_tag_link($tag->term_id).'" title="'.$tag->name.'">'. $tag->name .'</a>'; 
            } ?>

This should be used in your single.php or the template that renders the content of your post. get_the_term() itself can be used anywhere, but since you have to pass the post's ID to it, you should use it in the proper template files.

  • It is indeed inside single-work.php that I'm working. I tried your code but it's still just blank. The entire echo disappears without even an error message.
    – dem0n
    Jul 16, 2017 at 18:27
  • @dem0n Use this and add the output to your question : print_r($post_tags);
    – Johansson
    Jul 16, 2017 at 18:30
  • 2
    What about the_terms( $id, $taxonomy, $before, $sep, $after ); and skip the foreach loop ?
    – birgire
    Jul 16, 2017 at 18:32
  • @birgire Sure, Is it possible to use get_tag_link($tag->term_id) as an argument too?
    – Johansson
    Jul 16, 2017 at 18:34
  • 1
    It should be included as it uses get_the_term_list()
    – birgire
    Jul 16, 2017 at 18:37

This is the expected behaviour of get_terms(). You can use wp_get_object_terms() instead

$terms = wp_get_object_terms( $post->ID, 'portfolio_tags_client' );

If you are inside the loop, you can use the following instead

$terms = wp_get_object_terms( get_the_ID(), 'portfolio_tags_client' );
  • Hmm. When I do the following, it just disappears entirely: ` <?php $terms = wp_get_object_terms( $post->ID, 'portfolio_tags_client' ); foreach ( $terms as $term ) { $term_link = get_term_link( $term ); if ( is_wp_error( $term_link ) ) { continue; } echo 'Client: <a href="' . esc_url( $term_link ) . '">' . $term->name . '</a>&nbsp;<br />'; } ?> `
    – dem0n
    Jul 16, 2017 at 17:40
  • Well, do you have a $post variable in the scope? Depending on where your code is, try get_the_ID() instead
    – kero
    Jul 16, 2017 at 17:41
  • Sorry I'm not entirely sure what you mean. Where should I put that?
    – dem0n
    Jul 16, 2017 at 17:44
  • @dem0n Please see the update to my answer
    – kero
    Jul 16, 2017 at 17:51
  • Thanks for your efforts, kero, but now nothing is showing up. The entire echo has disappeared from the page. Not even an error message.
    – dem0n
    Jul 16, 2017 at 17:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.