5

I have a custom taxonomy "role" for my custom post type "People".

When listing the roles, is there a way to exclude roles based on slug and not ID via get_terms function?

I ask because I'm running a multisite and a few websites have the same IDs as the ones I'd like to exclude.

Right now I have:

<?php
$roles = get_terms(
    'role', array(
    'orderby'       => 'ID',
    'order'         => 'ASC',
    'hide_empty'    => true,
    'exclude'       => array('58', '63', '833'),
    ));
$count_roles = count($roles);
if ( $count_roles > 0 ) : ?>
     //do stuff
<?php endif;?>

The slugs I'd like to exclude are: 'slug' => ['graduate', 'job-market-candidate', 'graduate-student','research'], but I don't know where to fit this line, if anywhere.

Any help is appreciated!

1
  • What about including what you need?
    – birgire
    May 24, 2018 at 16:42

2 Answers 2

9

The get_terms() (see docs) function accepts the same args as WP_Term_Query(see docs)
You have to get those terms Ids first and then pass it to the exclude arg:

// default to not exclude terms
$ids_to_exclude = array();
$get_terms_to_exclude =  get_terms(
    array(
        'fields'  => 'ids',
        'slug'    => array( 
            'graduate', 
            'job-market-candidate', 
            'graduate-student',
            'research' ),
        'taxonomy' => 'role',
    )
);
if( !is_wp_error( $get_terms_to_exclude ) && count($get_terms_to_exclude) > 0){
    $ids_to_exclude = $get_terms_to_exclude; 
}
$roles = get_terms(
    array(
        'orderby'    => 'ID',
        'order'      => 'ASC',
        'hide_empty' => true,
        'exclude'    => $ids_to_exclude,
        'taxonomy'   => 'role',
    )
);

$count_roles = count($roles);

if ( $count_roles > 0 ) : ?>
     //do stuff
<?php endif;?>
3
  • This worked great! The only edit I had to make was to add 'role', array( after $get_terms_to_exclude = get_terms(
    – timmyg
    May 30, 2018 at 14:00
  • 1
    Hi @timmyg I've updated my answer to include the ´taxonomy´ parameter, Note that since 4.5.0, taxonomies should be passed via the ‘taxonomy’ argument in the $args array:
    – Pabamato
    Jun 1, 2018 at 17:46
  • good code, thanks Sep 2, 2023 at 13:15
2

There's no option to exclude by slug in get_terms(). You'll need to get the IDs of the terms you want based on their slug, then exclude those IDs, as in Pabamato's answer.

But you'll probably have better performance just skipping over them on output, rather that slowing down the query with the exclude, or making additional queries.

$count_roles = count( $roles );

if ( $count_roles > 0 ) :
    $exclude = ['graduate', 'job-market-candidate', 'graduate-student','research'];

    foreach ( $roles as $role ) {
        if ( ! in_array( $role->slug, $exclude ) ) {
            continue;
        }

        // Do stuff.
    }
endif;

Or you could remove the relevant terms from the result set after retrieving them by using array_filter(), then proceed as normal.

$exclude = ['graduate', 'job-market-candidate', 'graduate-student','research'];

$roles = get_terms( array(
    'taxonomy'   => 'role',
    'orderby'    => 'ID',
    'order'      => 'ASC',
    'hide_empty' => true,
) );

$roles = array_filter( $roles, function( $role ) {
    return in_array( $role->slug, $exclude ) ? false : true;
} );

$count_roles = count( $roles );
2
  • ps: there's actually no need for the ? false : true part as in_array() is boolean.
    – birgire
    May 24, 2018 at 16:36
  • 3
    Yes but the value would be opposite to what was needed. The alternative was ! in_array() but the ! is harder to see and a little less clear about what was happening. I wanted to show the words true and false to make it more explicit how array_filter() worked. May 24, 2018 at 16:43

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.