Save up to 25% on pro security plugins w/ our Security Bundle »
Web Dev + WordPress + Security

WordPress pre_get_posts + Combined Category Archives

This is a quick post following from the latest redesign of my WordPress plugins website, Plugin Planet. There, I make use of WordPress great query functionality to display archives of multiple categories. For example, here is the combined archive for BBQ Pro and Docs. So that category archive displays all documentation posts for BBQ Pro. Likewise for other categories, for example here is the combined archive for Banhammer Pro and Tutorials. That category archive displays all tutorial posts for Banhammer Pro. These combined category archives are used for all pro plugins.


Combining categories via URL

To get a better idea of how it works, consider the following URL:

Combining the categories docs and bbq-pro, gives us the archive view for BBQ Pro Documentation. Another quick example:

Combining the categories tuts and banhammer-pro, gives us the archive view for Banhammer Pro Tutorials.

The trick here is to use the plus sign + to combine category slugs in the URL. You can combine any number of categories, and awesome WordPress will output the correct posts. Incidentally, WordPress also will output RSS and Atom feeds when /feed/ is appended to the URL. For example:

That calls up the RSS feed for the combined category archive for all Blackhole Pro tutorials. For more information, check out What is My WordPress Feed URL?

Modifying combined category queries

All good so far. But I also need to modify the query of my combined category archives. Specifically, I want to customize the number of posts that are displayed for various category views. For single-category archives, WordPress makes this easy:

function shapeSpace_set_posts_per_category($query) {
	if (!is_admin() && $query->is_main_query() && $query->is_category()) {
		if (is_category('news'))  $query->set('posts_per_page', 5);
		if (is_category('docs'))  $query->set('posts_per_page', 6);
		if (is_category('tuts'))  $query->set('posts_per_page', 8);
		if (is_category('forum')) $query->set('posts_per_page', 8);
add_filter('pre_get_posts', 'shapeSpace_set_posts_per_category');

This code snippet uses the filter hook pre_get_posts and the function is_category() to match specific individual categories and set the desired number of posts displayed per page. This is routine stuff. No surprises here.

Problem with combined categories

The problem is when you try using is_category() with multiple category names. It just doesn’t work. So you can check if the category is any single category slug like docs or tuts. But you can’t check if the category is a combined category like docs+bbq-pro or tuts+bbq-pro. For example if we try the following query:

..the result is a bunch of errors like:

PHP Notice: Trying to get property 'slug' of non-object in /wp-includes/class-wp-query.php on line 3765
PHP Notice: Trying to get property 'name' of non-object in /wp-includes/class-wp-query.php on line 3763
PHP Notice: Trying to get property 'term_id' of non-object in /wp-includes/class-wp-query.php on line 3761

Workaround solution

So back to Plugin Planet and my silly desire to customize the number of posts per combined-category archive page. How to make it work? The solution is to workaround is_category() with some alternate PHP logic:

function shapeSpace_set_posts_per_category($q) {
	if (!is_admin() && $q->is_main_query()) {
		$vars = $q->query_vars;
		$cat = isset($vars['category_name']) ? $vars['category_name'] : null;
		if (stripos($cat, 'news')  !== false) $q->set('posts_per_page', 5);
		if (stripos($cat, 'docs')  !== false) $q->set('posts_per_page', 6);
		if (stripos($cat, 'tuts')  !== false) $q->set('posts_per_page', 8);
		if (stripos($cat, 'forum') !== false) $q->set('posts_per_page', 8);
add_filter('pre_get_posts', 'shapeSpace_set_posts_per_category');

Basically this alternate technique replaces is_category() with query_vars category_name, which then is checked using PHP’s stripos(). I encourage you to compare this alternate code with the original technique. This code has been in place at Plugin Planet for over a year now and seems to be working perfectly.

Better solutions?

If you have a better solution for modifying combined category queries with WordPress, please share in the comments below (if open), or send a quick email via my contact form. Thank you kindly :)

Jeff Starr
About the Author
Jeff Starr = Fullstack Developer. Book Author. Teacher. Human Being.
Wizard’s SQL for WordPress: Over 300+ recipes! Check the Demo »
Perishable Press is operated by Jeff Starr, a professional web developer and book author with two decades of experience. Here you will find posts about web development, WordPress, security, and more »
.htaccess made easy: Improve site performance and security.
Fall season almost here :)
My greatest skill on social media is the ability to simply ignore 98% and keep scrolling without interacting.
Enjoying this summer, getting some great positive energy. Refreshing and inspiring.
☀️ Pro plugin giveaway! Enter to win 1 of 4 lifetime licenses for our WordPress security plugins, including 10-site Security Bundle!
There is no end to what humans can achieve when they work together.
Excellent (and free) tool to test your site's SSL configuration.
Plugin updates! All of our free and pro plugins ready for WordPress 6.2.
Get news, updates, deals & tips via email.
Email kept private. Easy unsubscribe anytime.