Filter get_categories() for taxonomy term in WordPress

I want to show a category only if a (custom) post is in that category AND region = $name for that post.

So, e.g. I have a custom post (type “business”) named “Mamma Mia” in child-category: “pizzerias” (and in parent-category “food”), and in region “Rotterdam” (custom taxonomy: “region”, custom taxonomy term: “rotterdam”).

Read More

=> display category “pizzerias” (and parent-category “food”)

Only, I have no clue how to accomplish this. I’d appreciate any help on this puzzle.

<?php 

// $filter = array('region'=>$name); 

$categories = get_categories(); 
foreach ($categories as $cat) 
{ 
    if($cat->parent < 1) 
    { 
    $cat_name = $cat->cat_name; 
    $catid = get_cat_ID( $cat_name ); 
    echo $cat_name. '<br/>'; 

    $args=array( 
      'orderby' => 'name', 
      'order' => 'ASC', 
      'child_of' => $catid 
      ); 
    $categories=get_categories($args); 
      foreach($categories as $category) {  
        echo '<a href="' . get_category_link( $category->term_id ) . '" title="' . sprintf( __( "View all posts in %s" ), $category->name ) . '" ' . '>' . $category->name.'</a><br/>'; 
        }  

    } 
} 

// print_r($categories);  


?>

Related posts

Leave a Reply

8 comments

  1. General idea – query for specific set of posts, gather all of their categories, filter, let function beat them in shape.

    Generic code:

    $posts = get_posts(array(
        'tag' => 'linux'
    ));
    
    $categories = array();
    
    foreach( $posts as $post ) {
    
        $cats = get_the_category($post->ID);
    
        foreach($cats as $c)
            $categories[] = $c->term_id;
    }
    
    $categories = array_unique($categories);
    sort($categories);
    $categories = implode(',', $categories);
    
    $result = get_categories(array(
        'include' => $categories
    ));
    

    Issues are – as I remember decent queries for multiple taxonomies will only come in WP 3.1 and this might get very intensive so will take caching (probably for each region).

  2. On the version of wordpress I’m using which is version 3.1.2. If you were to add ‘taxonomy’ => ‘taxonomy_term’ to the array of args it should work. So here’s a modification to your original code to include the taxonomy in the array. Don’t know the taxonomy name you’re trying to use or not though:

    <?php 
    
    // $filter = array('region'=>$name); 
    
    $categories = get_categories(); 
    foreach ($categories as $cat) 
    { 
        if($cat->parent < 1) 
        { 
        $cat_name = $cat->cat_name; 
        $catid = get_cat_ID( $cat_name ); 
        echo $cat_name. '<br/>'; 
    
        $args=array( 
          'taxonomy' => 'taxonomy_term', 
          'orderby' => 'name', 
          'order' => 'ASC', 
          'child_of' => $catid 
          ); 
        $categories=get_categories($args); 
          foreach($categories as $category) {  
            echo '<a href="' . get_category_link( $category->term_id ) . '" title="' . sprintf( __( "View all posts in %s" ), $category->name ) . '" ' . '>' . $category->name.'</a><br/>'; 
            }  
    
        } 
    } 
    
    // print_r($categories);  
    ?>
    
  3. I’ve adapted @rarst’s answer from above to use 3 custom taxonomies. I only want to spit out the terms that are attached to one or more of the posts in the loop.

    Here’s my function that I’ve added to functions.php:

    function dv_setup_sidebar_cats() {
        global $wp_query;
    
        $designers = array();
        $sizes     = array();
        $colors    = array();
    
        foreach( $wp_query->posts as $post ) {
    
            $des   = get_the_terms($post->ID, 'designer');
            $siz   = get_the_terms($post->ID, 'size');
            $col   = get_the_terms($post->ID, 'color');    
    
            foreach($des as $d) {
                $designers[] = $d->term_id;
            }
    
            foreach($siz as $s) {
                $sizes[] = $s->term_id;
            }
    
            foreach($col as $c) {
                $colors[] = $c->term_id;
            }
    
        }
    
        if ( !empty($designers) ) {
            $designers = array_unique($designers);
            sort($designers);
            $designers = implode(',', $designers);
    
            $dresult   = get_categories(array(
                'include'  => $designers,
                'taxonomy' => 'designer'
            ));
        }
    
        if ( !empty($sizes) ) {
            $sizes = array_unique($sizes);
            sort($sizes);
            $sizes = implode(',', $sizes);
    
            $sresult   = get_categories(array(
                'include'  => $sizes,
                'taxonomy' => 'size'
            ));
        } 
    
        if ( !empty($colors) ) {
            $colors = array_unique($colors);
            sort($colors);
            $colors = implode(',', $colors);
    
            $cresult   = get_categories(array(
                'include'  => $colors,
                'taxonomy' => 'color'
            ));
        }
    
        $return = array(
            'size'     => $sresult,
            'color'    => $cresult,
            'designer' => $dresult
        );
    
    
        return $return;
    
    }
    

    Hope this helps someone else.

    -J

  4. Forgive me if I’ve missed something, but would it not be as simple as;

    if (is_object_in_term($post->ID, 'region', 'rotterdam'))
        the_category(); // displays categories associated with current post
    

    In the admin, are you attaching the post to both ‘pizzerias’ and ‘food’ (by ticking both checkboxes), or just ‘pizzerias’?

    If the latter, the_category() won’t show ‘Food’ by default, so you’ll have to grab the category hierarchy yourself.

  5. you can return the taxonomie for custom post with a small funtion:

        function get_the_taxonomy( $taxonomy, $id = FALSE ) {
            global $post;
    
            $id = (int) $id;
            if ( !$id )
                $id = (int) $post->ID;
    
            $categories = get_object_term_cache( $id, $taxonomy );
            if ( FALSE === $categories ) {
                $categories = wp_get_object_terms( $id, $taxonomy );
                wp_cache_add($id, $categories, $taxonomy . '_relationships');
            }
    
            if ( !empty( $categories ) )
                usort( $categories, '_usort_terms_by_name' );
            else
                $categories = array();
    
            foreach ( (array) array_keys( $categories ) as $key ) {
                _make_cat_compat( $categories[$key] );
            }
    
            return $categories;
        }
    

    Also you can use the function of wp-core:

    $taxonomys = get_the_term_list($id, YOUR_CUSTOM_POST_TYPE, '', ', ', '' );
    

    and you can ask for tax with is_tax(), see codex for this conditional tag

    Maybe this helps, when i understand your problem right. Sorry for my bad english.

  6. Thank you all for helping me out – that’s really great. I’d like to share with you what I’ve come up with. I know it is not the smartest solution. The drawback is that a parent category is shown for a region, when there is no custom post attached to it for this region (but there is a custom post attached to it for an other region).

    I am using this on a region (taxonomy archive) page.

    <?php
    $categories = get_categories();
    foreach ($categories as $cat)
    {
        if($cat->parent < 1)
        {
            $cat_name = $cat->cat_name;                         
            $catid = get_cat_ID( $cat_name );
    
            echo '<div class="indexcolumn-top">';
    
            $img = $taxonomy_images_plugin->get_image_html( 'fullsize', $cat->term_taxonomy_id );
            if( !empty( $img ) )
                print $img;
            else 
                echo '<h2>' .$cat_name. '</h2>';
    
            $input = array();
            $args=array(
              'child_of' => $catid,
              'orderby' => 'name',
              'order' => 'ASC'
              );
    
            $categories = get_categories($args);
            foreach ($categories as $cat)
            {
                $cat_name = $cat->cat_name;
                $catid = get_cat_ID( $cat_name );
    
                $args = array(
                    'post_status' => 'publish',
                    'taxonomy_name' => 'region',
                    'taxonomy_term' => $name,
                );
                $custom_posts = get_posts_by_taxonomy($args);
                if ($custom_posts):
                    foreach ($custom_posts as $post):
                        setup_postdata($post);
                        $postcategory = get_the_category(); $postcat = $postcategory[0]->cat_name;
                        if ($postcat == $cat_name):
                            $category = get_the_category(); 
                            $input[] = $catid;
                        endif;
                    endforeach;
                endif;
            }
            echo '<br/>';
            $output = array_unique($input);
            if (empty($output)):
                echo '<p>Geen bedrijven</p>';
                echo '</div>';
            else :
                echo '<ul class="port-box">';
                foreach ($output as $output) {
                    $cat_name = get_cat_name($output);  
                    echo '<li><a href="' . get_category_link($output) . '" title="' . sprintf( __( "View all posts in %s" ), $cat_name ) . '" ' . '>' . $cat_name .'</a></li>';                             
                }
                echo '</ul></div>';
            endif;
        }                                                   
    }
    ?>
    
  7. <?php $cat_id = $_GET["cat"];?>     
          <li id="category-active"><a><?php if ($cat_id){echo get_the_category_by_id($li_id);}else{ echo "Selectedcategory";}?></a></li>            <?php   $subcategories1 = wp_list_categories("title_li&child_of=$cat_id&hide_empty");
                    wp_list_categories("title_li=&current_category="); ?>
                        </ul><?php ?>
    

    thanks for your help.

    but i think their is no need of foreach or any loop we can get child of any category by using this simple code first $li_id get the current cat id and we dynamicaly passed this id to child_of=$cat_id and it show the selected cat childs i am using it in my site side bar.