get_categories() for only CPT

On the site that I am working on I have Jobs as a custom post type and Locations as custom taxonomy. The Locations are used by Jobs, Posts, and other CPTs.

I am working on a small filter for the jobs and want to show a list of all Locations as links that after you click on one it will sort the page to show only Jobs at that location. Using simple link queries.

Read More

I am using get_categories() to generate the list of locations, but the problem with that function is that will not allow me to specify Post Type and shows all locations that have any type of post. So I end up with a list of locations that not all have jobs and when click on the link it will show an 404 page.

            <?php      
          $args = array(
            'type'                     => 'post', //changing this to jobs does not have any effect...
            'child_of'                 => 0,
            'parent'                   => 0,
            'orderby'                  => 'count',
            'order'                    => 'DESC',
            'hide_empty'               => 1,
            'hierarchical'             => 0,
            'exclude'                  => '',
            'include'                  => '',
            'number'                   => '9999',
            'taxonomy'                 => 'location',
            'depth'                    => 0,
            'pad_counts'               =>  true);

          $categories = get_categories($args);
            $checked = false;
            foreach($categories as $category) {
              echo '<li><a href="/jobs/?location='.$category->slug.'">'.$category->name.'</a></li>';
            } 
          ?>

How to tell get_categories() to show only post_type => Jobs?
Is there another way to show a list of locations and hide the ones that do not have jobs in them?

Thanks in advance!

Related posts

Leave a Reply

2 comments

  1. You should use wp_get_post_terms() instead of get_categories(). It returns an array of terms associated with a post.

    <?php
    function get_my_custom_terms() {
        global $post;
        $myterms = wp_get_post_terms($post->ID, 'location');
    
        if ($myterms) {
            foreach($myterms as $term) {
                $termname = $term->name;
                $term_link = get_term_link( $term->slug, 'location' );
                    if( is_wp_error( $term_link ) ) {
                        $termlink = $term_link;
                    } else {
                        $termlink = '/jobs/?location=' .$term->slug;
                    }
                echo '<li><a href="' . $termlink . '">'. $termname .'</a></li>';
            }
        }
    }
    
  2. get_categories has no concept of post type, it only looks a the taxonomy term, and that terms post count. The post count is not generated at runtime, nor are there different counts for different post types.

    Instead, to get what you want, you should do one of the following:

    • register a custom count callback, which would count only the jobs posts. The downside of this is that the count will always be of job posts, other posts will not be able to have their own counts.
    • Force the listings to only show jobs. However this will prevent listings of other post types.

    Finally, my recommended method:

    Create a taxonomy for job locations. What you’re trying to do fails to acknowledge that the location of a job is not the same as a location of a post or other post type, and each should have separate taxonomies for location if they are to be listed and counted separately.

    If then you need to do more complex URLs and comparisons between taxonomies, I suggest this as reading material:

    http://thereforei.am/2011/10/28/advanced-taxonomy-queries-with-pretty-urls/