Modifying the WordPress query in your theme without breaking plugins

In the WordPress codex, it explains how to modify what posts are in the loop by modifying the WordPress Query object. However there is a catch with this, because by using rewind_posts() for example, you are generating a brand new query to the database that doesn’t trigger plugins.

Specifically this came up when creating the current theme for my webpage. I wanted to use my tdo-tag-fixes plugin that filters posts on a category template based on a tag. This initially worked fine, but I wanted to tweak the theme so that some category pages displayed all posts from that category but yet could be filtered by tags. (Check out my download section where you can filter downloads by clicking on the tag cloud on the left). Apparently other people are suffering similar problems too when they use the tdo-tag-fixes plugin while trying to modify the query within their theme.

To list all the posts in a category template isn’t hard at all. I just had to set the query var “nopaging” to true and do a rewind_posts(). (You also have to set the category_name again). Once I had implemented this in my category template, the tag filtering stopped working. What was happening was that rrewind_posts() created a brand new query, overwriting any previous set query vars and basically going around my tdo-tag-fixes plugin.

However there is a solution to this (basically how tdo-tag-fixes is implemented in fact). So what you need to do is modify the query before it gets to the template. This way it should be in addition to any other plugins that modify the query (unless your theme overwrites them).

So in my functions.php I did something like this:


add_action('parse_request','show_all_entries_in_category');

function show_all_entries_in_category(
    $args
) 
{
    $categories_list = array( 1, 3, 4 );
    
    // this if checks if it's for a category template
    //
    if(isset($args->query_vars['category_name'])) 
    {
    
        $cat = get_category_by_path($args->query_vars['category_name']);
        
        // if one of the special categories, disable paging
        //
        if(in_array($cat->term_id,$categories_list)) 
        {
            // make sure all posts are displayed in this category
            //
            $args->set_query_var('nopaging',true);
        }
    }
}

This piece of code will check set the “nopaging” query var on the wp_query for categories with ids 1, 3 or 4, which means that for those category pages all posts will be listed with no previous and next page links.

You can of course alter the code with in show_all_entries_in_category() with what ever query modifications you need to do.

Related Posts: