0

I'd like to exclude categories from wp_list_categories() but I want to use the category slug because I do development on a local install where the category ID will be different in production. I got this to work with the following code:

$exclcat            = array( 'fp-feature', 'fp-aside-feature' );                               
$output_categories  = array();
$categories         = get_categories( $args );

foreach( $categories as $category ) { 
    if( in_array( $category->slug, $exclcat ) ) {
        $output_categories[ $category->cat_ID ] = $category->cat_ID;
    }
}

$args = array(
    'orderby'            => 'ID',
    'show_count'         => 0, //Use 1 to show the count
    'taxonomy'           => 'category',
    'use_desc_for_title' => 1,
    'echo'               => 1, //Use 0 to not output results
    'title_li'           => '', //creates an <li> entry with text entered here - can be blank
    'exclude'            => $output_categories,
);

wp_list_categories( $args );

Is this the proper way to do it or is there a more efficient way?

2

I would suggest a cleaner approach would be to implement an exclude_slugs argument for the function, then you can just use the following in your template code:

wp_list_categories([
    'exclude_slugs' => [ 'fp-feature', 'fp-aside-feature' ],

    // Other arguments
]);

Here's the filter, pop it in your functions.php:

function wpse_217847_list_terms_exclusions( $query, $args ) {
    if ( ! empty( $args['exclude_slugs'] ) ) {
        if ( ! is_array( $slugs = $args['exclude_slugs'] ) )
            $slugs = array_map( 'trim', explode( ',', $slugs ) );

        $slugs  = array_map( 'esc_sql', $slugs );
        $slugs  = implode( '","', $slugs );
        $query .= sprintf( ' AND t.slug NOT IN ("%s")', $slugs );
    }

    return $query;
}

add_filter( 'list_terms_exclusions', 'wpse_217847_list_terms_exclusions', 10, 2 );

Bonus points: no additional db queries needed to first get the slug => ID translations.

1

Instead of getting all categories you could just loop through your excluded slug array and use get_term_by():

$exclude_slugs      = array( 'fp-feature', 'fp-aside-feature' );                               
$exclude_ids        = array();

foreach( $exclude_slugs as $slug ) { 
    $tmp_term = get_term_by( 'slug', $slug, 'category' );

    if( is_object( $tmp_term ) ) {
        $exclude_ids[] = $tmp_term->term_id;
    }
}

$args = array(
    'orderby'            => 'ID',
    'show_count'         => 0, //Use 1 to show the count
    'taxonomy'           => 'category',
    'use_desc_for_title' => 1,
    'echo'               => 1, //Use 0 to not output results
    'title_li'           => '', //creates an <li> entry with text entered here - can be blank
    'exclude'            => $exclude_ids,
);

wp_list_categories( $args );

This will make sure we only get terms that we want to exclude.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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