WordPress Wednesdays: Creating Custom Queries in WordPress

WordPress automatically loads the appropriate posts and pages on your site based on its default database queries. However, it’s possible to create custom queries so you can call whatever content you like from the SQL database and run it through the WordPress Loop — the code used to display your WordPress posts — wherever you want on your site. You can do this by tweaking the global $wp_query to change a page’s output, or create your own queries from scratch.

For an out-of-the-box blog, there is rarely a need to alter what WordPress loads on each page. However, custom queries can be helpful when you need more control over the page content – whether it’s hiding or showing specific categories, changing how many posts load on a page, or just excluding a post or two from displaying at all.

Below, we show you a few basic examples of custom queries. As with all template changes, make sure to back up your theme files before making any edits.

Creating a new query

The most basic way to create a new query in WordPress is to use the query_posts() function; this will overwrite what the WordPress query would normally be and replace it with your new query.

The below query would call posts with a specific category. It must be placed before the start of the WordPress Loop:

<?php query_posts( 'cat=4' ); ?>

<!-- Start of WordPress Loop -->
<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>

Using query_posts() alters the main WordPress Loop – this means it overwrites any other information that would normally be passed to the Loop, like the pagination, or that the page is, say, a category archive.

It’s a good idea to use the wp_reset_query() function after you have used query_posts(), to return the Loop’s default setting:

<?php endwhile; endif; ?>
<!-- End of WordPress Loop -->

<?php wp_reset_query(); ?>

Tweaking the existing query using global variables

WordPress stores the query related to the current page in the global $wp_query object. If you just need to change a page’s query slightly, but still want to maintain the other settings (like pagination), you can append parameters to the global query quite easily.

For example, to restrict the global $wp_query object to only one category, you can merge it with your own array containing this parameter, and then make this new, merged query the page’s new query. Place this PHP before the start of the WordPress Loop, and the page will use your modified query:

<?php
global $wp_query;
$args = array_merge( $wp_query->query, array( 'cat' => '4' ) );
query_posts( $args );

?>

<!-- Start of WordPress Loop -->
<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>

You can also use the global $query_string object instead; in this example, we simply appended our own category restriction, and made that the page’s query:

<?php
global $query_string;
query_posts( $query_string . '&cat=4' );
?>

<!-- Start of WordPress Loop -->
<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>

Because query_posts() is being altered like in the previous example, it’s a good idea to use wp_reset_query() after the Loop:

<?php endwhile; endif; ?>
<!-- End of WordPress Loop -->

<?php wp_reset_query(); ?>

Create a basic custom query

Rather than simply appending values the global $wp_query object, it is also possible to create your own WordPress query from scratch by declaring a new instance of the WP_Query class.

Let’s say you wanted to create a query that would select five posts from a specific category — you would create a new instance of the WP_Query class with your query’s parameters. Unlike the previous example, it is necessary to tweak the Loop code to reference this new query. In the example below, we stored the new query in a variable called $newQuery; then, in each instance of the loop, we prefaced the function with $newQuery-> (ie. $newQuery->have_posts(), $newQuery->the_post(), etc.).

A very basic example of this code would look like  the following:

<?php

$newQuery = new WP_Query(array('posts_per_page'=>'5', 'cat' =>'4'));

// Start of modified WordPress Loop
if ($newQuery->have_posts()) : while ($newQuery-> have_posts()) : $newQuery->the_post(); ?>

<?php the_title(); ?>
<?php the_content(); ?>

<?php endwhile; endif; ?>

Because you are creating a new query, rather than altering query_posts(), it’s not necessary to use the wp_reset_query() function.

There are many parameters you can use in your custom query, documented in the WordPress Codex.

Dynamically query childpages of the current page

This last example is a little more complex, but can be very useful when using WordPress as a CMS for a regular site. It uses a custom query, as well as the parent-child relationship you can create in WordPress pages.

When you create a custom query that used its own Loop, like in the example above, it’s possible to nest the custom query inside of the official Loop.

In this scenario, on a section’s landing page, it may be necessary to list the ‘child pages’ within that section — this could be very useful, say, on a ‘Practice Areas’ page to list the specific practice groups and link to them.

Within the page’s loop, you can add a custom query that uses the current page’s ID to query its childpages, and then display an unordered of the childpage titles:

<?php
$childPages = new WP_Query(array('post_parent'=>$post-> ID,'post_type'=>'page'));
if ($childPages->have_posts()) : ?>
<ul>

<?php while ($childPages->have_posts()) : $childPages->the_post(); ?>
<li><?php the_title(); ?></li>

<?php endwhile; ?>
</ul>
<?php endif; ?>

In this example, the Loop’s if statement is used as well, so the surrounding <ul> tags are only displayed if there are actually childpages.

Now, when childpages are added or edited, this information is automatically updated on the parent page as well. For a more advanced example, check out the practice area page on Thorsteinssons’ new website.

We’d love to hear how you use custom queries on your own WordPress site — share your examples in the comments!

Comments

  1. Madan said:

    Great post. I was wondering how to make my special blog posts displayed in the home page. Laurel provides a clear idea on implementing it.

    Cheers,
    Madan

    @ 11:28 pm
  2. […] to append the shorter query to the existing WordPress query rather than overwrite it, like in the previous WordPress Wednesday’s post about custom queries. This way, it’s possible to lower the number of posts being queried, but still maintain other […]

    @ 5:49 am