Creating Custom Queries for Multiple Categories
Basic Approach
To display posts from multiple categories, you can use WordPress's WP_Query
class or modify the main query using pre_get_posts
. Here are the most effective methods:
Method 1: Using WP_Query
Basic example to fetch posts from multiple categories:
$args = array(
'category__in' => array(4, 7, 12), // Add your category IDs
'posts_per_page' => 6,
'orderby' => 'date',
'order' => 'DESC'
);
$category_query = new WP_Query($args);
if ($category_query->have_posts()) :
while ($category_query->have_posts()) : $category_query->the_post();
get_template_part('template-parts/content');
endwhile;
wp_reset_postdata();
endif;
Method 2: Using Category Slugs
If you prefer using category slugs instead of IDs:
$args = array(
'category_name' => 'news,events,updates', // Comma-separated category slugs
'posts_per_page' => 6
);
$category_query = new WP_Query($args);
Advanced Implementation
For more complex filtering with pagination:
function get_multi_category_posts() {
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$args = array(
'category__in' => array(4, 7, 12),
'posts_per_page' => 9,
'paged' => $paged,
'orderby' => 'date',
'order' => 'DESC',
'post_status' => 'publish'
);
return new WP_Query($args);
}
// Usage
$multi_cat_query = get_multi_category_posts();
Security Best Practices
- Always sanitize input data if category IDs come from user input
- Use
wp_reset_postdata()
after your custom query
- Check user capabilities when necessary
- Validate category IDs before querying
Example with security measures:
function get_safe_category_posts($category_ids) {
// Sanitize input
$safe_ids = array_map('absint', (array) $category_ids);
// Verify categories exist
$safe_ids = array_filter($safe_ids, 'term_exists');
if (empty($safe_ids)) {
return false;
}
$args = array(
'category__in' => $safe_ids,
'posts_per_page' => 6,
'no_found_rows' => true, // Performance optimization
'post_status' => 'publish'
);
return new WP_Query($args);
}
Common Pitfalls to Avoid
- Not resetting post data after the query
- Using too many queries on one page
- Not implementing proper pagination
- Forgetting to check if posts exist
Performance Optimization
For better performance when you don't need pagination:
$args = array(
'category__in' => array(4, 7),
'posts_per_page' => 6,
'no_found_rows' => true,
'fields' => 'ids', // Only get post IDs if that's all you need
'cache_results' => true
);
Helpful Plugins
-
Query Monitor (link) - Debug and optimize your queries
-
Posts in Page (link) - Embed custom post queries using shortcodes
Alternative Approaches
- Using
pre_get_posts
for modifying main query
- Using tax_query for more complex taxonomy relationships
- Using category parameters in REST API calls
Template Integration
Example of how to integrate the query into a template:
<?php
/*
Template Name: Multi Category Template
*/
get_header();
$multi_cat_query = get_multi_category_posts();
if ($multi_cat_query->have_posts()) :
echo '<div class="post-grid">';
while ($multi_cat_query->have_posts()) : $multi_cat_query->the_post();
get_template_part('template-parts/content', 'category');
endwhile;
echo '</div>';
// Pagination
echo paginate_links(array(
'total' => $multi_cat_query->max_num_pages
));
wp_reset_postdata();
else :
get_template_part('template-parts/content', 'none');
endif;
get_footer();
Remember to test your queries thoroughly and monitor their performance impact on your site.