WordPress taxonomies are one of the most powerful content organization tools the platform provides. Categories and tags are the built-in examples, but developers regularly register custom taxonomies like genre, location, brand, or project-type alongside custom post types. At some point in almost every WordPress project you need to fetch all posts that belong to a specific term in one of those taxonomies. A theme might need to render a grid of portfolio items filtered by project type, a page template might loop through all products tagged with a particular brand, or a widget might list the three most recent articles in a chosen genre. The most reliable tool for this job is WP_Query with a tax_query parameter, which is designed exactly for taxonomy-based filtering. tax_query accepts an array of conditions that specify taxonomy name, term value, and the field type used for matching. You can match terms by ID, slug, or name — slug is usually the safest choice because term IDs change between development and production environments. WP_Query also respects post status, post type, and pagination arguments, so you can combine taxonomy filtering with other conditions in a single query instead of making multiple database calls. One critical detail to remember is that a custom WP_Query loop does not automatically restore the global $post object when it finishes. Forgetting to call wp_reset_postdata() after the loop breaks template tags like the_title() or get_the_ID() anywhere further down the same page. An alternative is get_posts(), which wraps WP_Query with simpler defaults and suppresses pagination filters, but gives you less control. For anything beyond a simple flat list, WP_Query with tax_query is the right approach. The example below fetches all published posts from a custom taxonomy called genre with the term slug thriller.
Problem: You need to retrieve all posts that belong to a specific term in a custom taxonomy.
Solution: Add the following code to your theme template file:
<?php
$args = array(
'post_type' => 'post',
'post_status' => 'publish',
'posts_per_page' => -1,
'tax_query' => array(
array(
'taxonomy' => 'genre',
'field' => 'slug',
'terms' => 'thriller',
),
),
);
$query = new WP_Query( $args );
if ( $query->have_posts() ) {
while ( $query->have_posts() ) {
$query->the_post();
the_title( '<h2>', '</h2>' );
}
wp_reset_postdata();
}
NOTE: Replace 'genre' with your custom taxonomy slug and 'thriller' with the target term slug. Setting 'posts_per_page' => -1 returns all matching posts at once — use a positive integer on large datasets to avoid memory issues. Always call wp_reset_postdata() after the loop to restore the global $post object and prevent template tag conflicts on the same page.