0

I have a few custom post types and two of them are sharing a custom taxonomy.

Is there a way to list the terms of that taxonomy for only one of the custom post types?

At the moment I can get a list of the terms and display them how I want, but its a mix of both custom post types. I need a way to somehow filter out the other post type.

Heres what I've got in my sidebar.php:

<?php
    $post_type = get_post_type();

    if($post_type == 'artists' || $post_type == 'educations') {
        $taxonomy = 'art_categories'; // Sharing same taxonomy
    } else {
        $taxonomy = $post_type.'_categories'; // Other post type taxonomy
    }

    $term = get_term_by("slug", get_query_var($taxonomy), $taxonomy);

    $children = get_term_children($term->term_id, $taxonomy);


    if(empty($children)) { // Cats with NO kids

        $parent = $term->parent;

    } elseif($term->term_id > 0) { // Cats with kids

        $parent = $term->term_id;

    } else { // TOP Level Cats

        $parent = 0;

    }   

    $args = array(
        "type" => $post_type,
        "taxonomy" => $taxonomy,
        "parent" => $parent,
        "exclude" => 2,
    );

    $categories = get_categories($args);


    if($categories) {

        echo "<ul>";

        foreach($categories as $cat) {

            echo "<li class='cat-item'>";

                echo "<a href='" . get_term_link($cat) . "'>" , $cat->name , "</a>";

            echo "</li>";

        }

        echo "</ul>";

    }

?>
1

1 Answer 1

0

You could try using the terms_clauses filter

function wpse156370_terms_clauses( $pieces, $taxonomies, $args ) {
    global $wpdb;
    $pieces['fields'] .= $wpdb->prepare( ', (SELECT COUNT(*) FROM '
        . $wpdb->posts . ' p, ' . $wpdb->term_relationships . ' p_tr'
        . ' WHERE p_tr.object_id = p.ID AND p_tr.term_taxonomy_id = tt.term_taxonomy_id'
        . ' AND p.post_status = %s AND p.post_type = %s) AS post_count', 'publish', $args['type'] );
    $pieces['orderby'] = ' HAVING post_count > 0 ' . $pieces['orderby'];
    return $pieces;
}

and then around the get_categories

    add_filter( 'terms_clauses', 'wpse156370_terms_clauses', 10, 3 );
    $categories = get_categories( $args );
    remove_filter( 'terms_clauses', 'wpse156370_terms_clauses', 10, 3 );

It's a hack, misusing HAVING (and $pieces['orderby']) as can't refer to the post_count alias in the WHERE, but ... seems to work.

To get the term links to differentiate add a query var to each, eg

echo "<a href='" . add_query_arg( 'post_type', $post_type, get_term_link($cat) ) . "'>" , $cat->name , "</a>";

And then check for this in a pre_get_posts action

function wpse156370_pre_get_posts($query) {
    $taxonomy = 'art_categories';
    $post_types = array( 'artists', 'educations' );
    if ($query->is_main_query() && $query->is_tax( $taxonomy ) && ( $post_type = get_query_var( 'post_type' ) ) && in_array( $post_type, $post_types ) ) {
        $query->set( 'post_type', $post_type );
    }
}
add_action( 'pre_get_posts', 'wpse156370_pre_get_posts' );
4
  • Didn't work. Got the following error: "Notice: Undefined index: post_type in functions.php on line 8"
    – ngearing
    Aug 1, 2014 at 1:37
  • Ok thought you passed $post_type as 'post_type' - should be 'type' - edited answer.
    – bonger
    Aug 1, 2014 at 4:14
  • Ace. That is working. But when I click on a term, the query is returning with both post types still. How can I add this filter to my loop?
    – ngearing
    Aug 5, 2014 at 0:45
  • Yes if you add a query var to the get_term_link() and then look for this in a pre_get_posts action - will update answer with example.
    – bonger
    Aug 5, 2014 at 1:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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