0

I'm trying to exclude a large amount of tags from being displayed in get_the_tags function. I have successfully excluded tags using this code:

<?php 
    $links = array(); 
    foreach (get_the_tags() as $this_tag) { 
        if ($this_tag->name != "test1" && $this_tag->name != "test2"){ 
            $links[] = '<a href="'.get_tag_link($this_tag->term_id).'" title="'.$this_tag->name.'">'.$this_tag->name.'</a>'; 
        } 
    } 
    echo implode(' • ', $links);
?>

However, the issue is there's new tags added regularly, and having to manually modify the exclude code isn't something i want to do, can i somehow specify an array of tags to INCLUDE and then automatically exclude every other tag from being displayed?

Any ideas how i could solve this?

EDIT

I do not wish to modify the original get_the_tags using filters in function.php as I display all tags at other places of the website

3
  • Are you excluding tags on a per post basis or exclude some tags for all posts?
    – birgire
    Commented Jan 6, 2016 at 10:47
  • per post basis, the code above runs on each post to display tags, but i do not wish to modify the original get_the_tags using filters in function.php as i display all tags at other places of the website. Commented Jan 6, 2016 at 10:53
  • So are you storing the excluding tags in a custom field?
    – birgire
    Commented Jan 6, 2016 at 11:53

1 Answer 1

2

EDIT

From your comment to your own question, you have two choices if you do not need to apply the filter globally to all instances of get_the_terms)

OPTION 1

Use the same logic as in my ORIGINAL ANSWER

$links = [];
$tags_to_include = [1, 2, 3]; // using ID's
foreach (get_the_tags() as $this_tag) {
    // If the tag is not in our include list, skip it 
    if ( !in_array( $this_tag->term_id, $tags_to_include ) ) // Change term_id to name or slug to match $tags_to_include
        continue;

    // If we are here, our tag is in the list
    $links[] = '<a href="'.get_tag_link( $this_tag ).'" title="'.$this_tag->name.'">'.$this_tag->name.'</a>'; 
} 
echo implode(' • ', $links);

OPTION 2

Still use the filter, but remove it when done

First define our call back function

function remove_some_tags( $terms, $post_id, $taxonomy )
{
    // Make sure we target only the post_tag taxonomy
    if ( 'post_tag' !== $taxonomy )
        return $terms;

    // Create an array of tags you want to INCLUDE, use tag id's, or slugs or names
    $tags_to_include = [1, 2, 3]; // using ID's
    //$tags_to_include = ['slug-1', 'slug-2', 'slug-3']; // using slugs
    //$tags_to_include = ['Name 1', 'Name 2', 'Name 3']; // using names

    // Now we can loop through our tags and exclude the one not in our included array
    foreach ( $terms as $key=>$term ) {
        // Skip tags that appear in the included list
        if ( in_array( $term->term_id, $tags_to_include ) ) // Change term_id to name or slug to match $tags_to_include
            continue;

        // Now we simply unset the tag if we reach this point
        unset( $terms[$key] );
    } // endforeach

    // return the array of tags
    return $terms;
}

Now you can do:

// Add our filter
add_filter( 'get_the_terms', 'remove_some_tags' );

$links = []; 
foreach (get_the_tags() as $this_tag) {  
    $links[] = '<a href="'.get_tag_link( $this_tag ).'" title="'.$this_tag->name.'">'.$this_tag->name.'</a>';  
} 
echo implode(' • ', $links);

// Remove the filter       
remove_filter( 'get_the_terms', 'remove_some_tags' );

ORIGINAL ANSWER

I'm not sure why do you add tags to posts that you just want to remove again in get_the_tags, but anyway, the best to option to exclude tags is to catch the array early and to remove the unneseccary before the array is returned. get_the_tags() uses get_the_terms() which is filterable through the get_the_terms.

So we can try the following:

add_filter( 'get_the_terms', function ( $terms, $post_id, $taxonomy )
{
    // Make sure we target only the post_tag taxonomy
    if ( 'post_tag' !== $taxonomy )
        return $terms;

    // Create an array of tags you want to INCLUDE, use tag id's, or slugs or names
    $tags_to_include = [1, 2, 3]; // using ID's
    //$tags_to_include = ['slug-1', 'slug-2', 'slug-3']; // using slugs
    //$tags_to_include = ['Name 1', 'Name 2', 'Name 3']; // using names

    // Now we can loop through our tags and exclude the one not in our included array
    foreach ( $terms as $key=>$term ) {
        // Skip tags that appear in the included list
        if ( in_array( $term->term_id, $tags_to_include ) ) // Change term_id to name or slug to match $tags_to_include
            continue;

        // Now we simply unset the tag if we reach this point
        unset( $terms[$key] );
    } // endforeach

    // return the array of tags
    return $terms;
}, 10, 3 );

Just note, this needs a bit of overheads to run, so I would still exclude the tags or not assign them when I create the posts

A final note, always, where possible, pass the complete tag object to get_tag_link(). It saves a lot on db calls and time. If you only pass the tag ID, get_tag_link() queries the db to get the complete tag object, which you already have, so

get_tag_link($this_tag->term_id)

should become

get_tag_link($this_tag)
4
  • The code runs but changes the original get_the_tags query, essentially what i am trying to do is separate 2 types of tags on a page, having them displayed in separate columns. So i use the code in my original post to display 1 column of tags i just exclude the ones i don't want to display, these tags are static and never changes. The second column is different, there are regularly new tags added here so i cannot do the exclude approach as it will lead to much manual work in the code, that's why i am trying to do the include thing instead. Commented Jan 6, 2016 at 11:26
  • I have updated my answer with two possible options. Hope that helps ;-) Commented Jan 6, 2016 at 11:35
  • My pleasure glad it worked out, enjoy ;-) Commented Jan 6, 2016 at 11:42
  • It's working fine. The only issue is that it prints some items I added even if there's no tag. Please help
    – BarryOvb
    Commented Mar 4, 2022 at 1:24

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.