Question

Is it possible, with WP_Query, to get all posts which have at least one category or custom taxonomy term set?

Was it helpful?

Solution

Yes, totally possible.

SCENARIO 1

If you need only one taxonomy, all you need to do is to get all the term ID's of all terms assigned to the taxonomy and then pass that array of term ID's to a tax_query

(Requires PHP5.4+)

$term_ids = get_terms( 
    'TAXONOMY_NAME', 
    [ // Array of arguments, see get_terms()
        'fields' => 'ids' // Get only term ids to make query lean
    ]
);
if (    $term_ids // Check if we have terms
     && !is_wp_error( $term_ids ) // Check for no WP_Error object
) {
    $args = [
        'tax_query' => [
            [
                'taxonomy' => 'TAXONOMY_NAME',
                'terms'    => $term_ids,
            ]
        ],
    ];
    $q = new WP_Query( $args );

    // Run your loop as needed. Remeber wp_reset_postdata() after the query
}

SCENARIO 2

If you need posts that should have terms assigned to multiple taxonomies, you can build a more complex query on the logic of SCENARIO 1

$taxonomies = ['TAXONOMY_NAME_1', 'TAXONOMY_NAME_2']; // Array of taxonomies, can also use get_taxonomies for all
$tax_array = []; // Set the variable to hold our tax query array values
foreach ( $taxonomies as $key=>$taxonomy ) {

    $term_ids = get_terms( 
        $taxonomy, 
        [ // Array of arguments, see get_terms()
            'fields' => 'ids' // Get only term ids to make query lean
        ]
    );
    if (    $term_ids // Check if we have terms
         && !is_wp_error( $term_ids ) // Check for no WP_Error object
    ) {
        $tax_array[$key] = [
            'taxonomy' => $taxonomy,
            'terms'    => $term_ids,
        ];
    }
}
$relation = 'OR'; // Set the tax_query relation, we will use OR
if ( $tax_array ) { // Check if we have a valid array 
    if ( count( $tax_array ) == 1 ) {
        $tax_query[] = $tax_array;
    } else {
        $tax_query = [
            'relation' => $relation,
            $tax_array
        ];
    }

    $args = [ // Set query arguments
        'tax_query' => $tax_query,
        // Any other query arguments that you might want to add
    ]; 
    $q = new WP_Query( $args );

    // Run your loop as needed. Remeber wp_reset_postdata() after the query
}

OTHER TIPS

UPDATE:

get_terms() now takes an array like this:

$terms = get_terms( array(
    'taxonomy' => 'post_tag',
    'hide_empty' => false,
) );

https://developer.wordpress.org/reference/functions/get_terms

Licensed under: CC-BY-SA with attribution
Not affiliated with wordpress.stackexchange
scroll top