Save 25% on our pro plugins with coupon code: SPRING2023
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 = Creative thinker. Passionate about free and open Web.
Blackhole Pro: Trap bad bots in a virtual black hole.

Leave a reply

Name and email required. Email kept private. Basic markup allowed. Please wrap any small/single-line code snippets with <code> tags. Wrap any long/multi-line snippets with <pre><code> tags. For more info, check out the Comment Policy and Privacy Policy.

Subscribe to comments on this post

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 »
Digging Into WordPress: Take your WordPress skills to the next level.
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.
Daylight savings is a complete waste of time and needs to be eliminated.
Got a couple of snow days here in mid-March. Fortunately it's not sticking.
I handle all email in real time as it comes in, perpetually clear inbox for years now.
Added some nice features to Wutsearch search engine launchpad. Now 21 engines!
.wp TLD plz :)
Get news, updates, deals & tips via email.
Email kept private. Easy unsubscribe anytime.