Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I have some utility categories that are only used by my theme. To help separate these categories I place them all as children of uncategorized.

How can I make sure that any call to wp_list_categories() excludes the child categories under "uncategorized" cat_id = 1?

I want this to work even if the call wp_list_categories() comes from a third party plugin that I don't control.

Perhaps a filter I can place in functions.php that intercepts any call for the wp_list_categories() function to attach the exlude_tree = '1' to the arguments.

For example, in my own categories plugin widget, I use this...

    <ul>
<?php
    $cat_args['title_li'] = '';
    $cat_args['exclude_tree'] = 1;
    wp_list_categories(apply_filters('widget_categories_args', $cat_args));
?>
    </ul>
share|improve this question
add comment

3 Answers

up vote 2 down vote accepted

Hi @Scott B:

UPDATE FROM PRIOR ANSWER: Due you my evidently poor reading comprehension skills(!) where I missed the requirement to filter out children (Thanks @Adam BlackStrom for calling attention to my oversight) I've modified the code provided.


I think you want to use the list_terms_exclusions filter hook. Add this to your plugin (or others needing the same add to the bottom of your theme's functions.php file):

function my_list_terms_exclusions($exclusions,$args) {
  $children = implode(',',get_term_children(1,'category'));
  $children = (empty($children) ? '' : ",$children");
  return $exclusions . " AND (t.term_id NOT IN (1{$children}))";
}

Of course the above will affect all category listings which you might not want so you might need to inspect the values in the $args array or more likely inspect other global state to only add the filter criteria only in the context(s) in which you need it.

If you have specifics we of where you need help limiting please ask a follow up question so we can help.

P.S. Also, I agree with Adam. If possible use a custom taxonomy.

share|improve this answer
    
Ah, I missed that filter as I was reading through get_terms()! Maybe that combined with get_term_children() is the answer; I assume your code will still return children of "Uncategorized." –  Annika Backstrom Aug 23 '10 at 18:50
    
@Adam: Not sure how to answer so I'll just explain. I took @Scott B's code and ran with echo+exit statements to output the value of $exclusions. It was " AND ( t.term_id <> 1 )" and without $cat_args['exclude_tree'] = 1; it was blank which told me to have the filter add it in. Reading the code it seemed to be excluding anything that is categorized with cat=1. I didn't explore or test beyond that. –  MikeSchinkel Aug 23 '10 at 18:59
    
Right, it does correctly exclude term_id 1 ("Uncategorized") but will still show child categories. To work for Scott, you would also need to explicitly exclude all the child categories of "Uncategorized." –  Annika Backstrom Aug 23 '10 at 19:10
    
@Adam - I may be missing something but reading @Scott B's comments it seems that he only needs to exclude the parent because he states. Maybe he'll help us and clarify which of these solutions addresses his specific use-case. –  MikeSchinkel Aug 23 '10 at 20:29
    
In his question he asks, "How can I make sure that any call to wp_list_categories() excludes the child categories under 'uncategorized' cat_id = 1?" –  Annika Backstrom Aug 23 '10 at 20:38
show 4 more comments

New answer based on OP comments:

There isn't a filter or hook you can use with wp_list_categories, but there is a filter on the get_categories function that it calls.

The get_categories function makes this call:

$taxonomy = apply_filters( 'get_categories_taxonomy', $args['taxonomy'], $args );

The $args variable in this case is an array constructed originally from wp_list_categories and then merged with 'taxonomy' => 'category'. So you should be able to add a filter here to always set exclude_tree='1'.

Just be sure to specify that your function takes two parameters:

function exclude_children($taxonomy, $args) {
    $args['exclude_tree'] => '1';
}

add_filter('get_categories_taxonomy', 'exclude_children', 10, 2);
share|improve this answer
    
HI EAMann, thanks for the quick response. I can exclude categories by passing a parent id without a problem, now. See my code above, the exclude_tree argument does just that. However, that's MY own plugin, so I have that luxury. I'm trying to (continued...) –  Scott B Aug 23 '10 at 16:06
    
...force that exclusion in my theme files so that the category is always excluded from any call to wp_list_categories... –  Scott B Aug 23 '10 at 16:07
    
@EAMann: as you've probably figured out you'd have to pass $args by reference (i.e. using &$args) for the above code to work, except WordPress passed a value when it runs apply_filter() so you can't do that, unfortunately. –  MikeSchinkel Aug 23 '10 at 18:22
    
@MikeSchinkel ... yeah, that's where I'm stuck at with this solution ... –  EAMann Aug 23 '10 at 18:28
add comment

Here's some code to modify get_terms() to exclude "Uncategorized" and any children:

// modify the term list to exclude "Uncategorized" and any children
function no_uncategorized( $terms, $taxonomies, $args ) {
    global $my_excluded_categories;

    $uncategorized = term_exists( 'Uncategorized', 'category' );

    $my_excluded_categories = get_term_children( $uncategorized['term_id'], 'category' );
    $my_excluded_categories[] = $uncategorized['term_id'];

    $terms = array_filter( $terms, 'no_uncategorized_filter' );

    return $terms;
}

// used by array_filter to exclude anything in the excluded categories
function no_uncategorized_filter( $category ) {
    global $my_excluded_categories;
    return !in_array( $category->term_id, $my_excluded_categories );
}

// only done during template_redirect (the public-facing site)
function do_template_redirect() {
    add_filter( 'get_terms', 'no_uncategorized', 10, 3 );
}
add_action( 'template_redirect', 'do_template_redirect' );

I think the real answer, though, is don't use categories, instead register your own taxonomy. No more hidden categories, just a private taxonomy that isn't picked up by wp_list_categories().

share|improve this answer
    
Adam, you are correct. Had I known about how to create my own taxonomies, it would have been the way to go. As it is, utilizing the built in categories system was a quick and easy way to do it, with minimal side effects :) I'll be checking out your suggestion for an upgrade of my theme... –  Scott B Aug 23 '10 at 18:35
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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