In every programming or script language, loops structure has its own importance. Generally WordPress follows PHP. But wordpress also has some specific ways to achieve loops functionality. If we look at ‘index.php’ file of theme , the loop is the part that typically begins with if(have_posts()) and contains all the tags and markup used to generate the page.
The default loop in wordpress works perfectly well in simple design but for more advanced designs with stuff like multiple and custom loops, more looping power is needed. WordPress provides us the flexibility with different ways to loop:
Default Loop
Loop with query_posts()
Loop with WP_Query()
Loop with get_posts()
Each of these looping methods is used in different situation with lot of same functioality and the query parameters are the same.
The Default loop
We can generally see wordpress default loop in ‘index.php’ file. like
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | <?php if (have_posts()) : while (have_posts()) : the_post(); ?> <div <?php post_class(); ?> id="post-<?php the_ID(); ?>"> <h1><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h1> <?php the_content(); ?> </div> <?php endwhile; ?> <div class="navigation"> <div class="next-posts"><?php next_posts_link(); ?></div> <div class="prev-posts"><?php previous_posts_link(); ?></div> </div> <?php else : ?> <div <?php post_class(); ?> id="post-<?php the_ID(); ?>"> <h1>Not Found</h1> </div> <?php endif; ?> |
So why it is “default”? because it uses the default query to loop through post content, making it the loop used like 99% for most themes. Its purpose is to loop through the posts stored in the database and echo their contents to the browser. Using WordPress’ template tags, it’s easy to display post titles, content, meta info, and much more.
Based on the query that is sent, the default loop will display a certain number of posts from a certain category from a certain date, and so on. So the default loop is perfect if you’re with the query that is sent, but it is also possible to customize the query and generate an entirely different set of posts.
Loop with query_posts()
query_posts() is a way to alter the main query that WordPress uses to display posts. We can either override the entire query or keep it around and just change a few parameters. To clean up after a call to query_posts, make a call to wp_reset_query(), and the original main query will be restored.
Here’s an example where query_posts is called before the default loop to exclude a specific category:
1 2 3 4 5 6 | <?php global $query_string; // required $posts = query_posts($query_string.'&cat=-9'); // exclude category 9 ?> <?php // DEFAULT LOOP GOES HERE ?> <?php wp_reset_query(); // reset the query ?> |
If you want to change the number of posts, exclude two categories, and display the results in ascending order. Easy. Just add some query_posts action before the default loop and wp_reset_query immediately after, like this:
1 2 3 4 5 6 | <?php global $query_string; // required $posts = query_posts($query_string.'&posts_per_page=3&cat=-6,-9&order=ASC'); ?> <?php // DEFAULT LOOP GOES HERE ?> <?php wp_reset_query(); // reset the query ?> |
Here we are keeping original query with us and overriding some parameters. Like this we can customized its parameters given in query_posts parameters
If we wanted to completely override the original query, we need to write like this..
1 | <?php $posts = query_posts('posts_per_page=3&cat=-6,-9&order=ASC'); ?> |
When to use? Use query_posts to modify the type of posts that are returned for a single loop. If we want to limit the number of posts, exclude posts from a certain category or tag, and so on. If more than one loop is required, multiple query_posts loops could work, but there is a much better way to do it using WP_Query.
Loop with WP_Query()
For full customization of any number of loops, WP_Query is the way to go. When used to modify a default loop, it looks similar to query_posts. For example, let’s exclude a specific category using WP_Query:
1 2 3 4 5 6 7 8 9 10 | <?php $custom_query = new WP_Query('cat=-'7); // exclude category 7 while($custom_query->have_posts()) : $custom_query->the_post(); ?> <div <?php post_class(); ?> id="post-<?php the_ID(); ?>"> <h1><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h1> <?php the_content(); ?> </div> <?php endwhile; ?> <?php wp_reset_postdata(); // reset the query ?> |
It also accepts the same parameters as query_posts so we can customize it like :
1 2 3 | $custom_query = new WP_Query('cat=-5,-6,-7'); // exclude any categories $custom_query = new WP_Query('posts_per_page=5'); // limit number of posts $custom_query = new WP_Query('order=ASC'); // reverse the post order |
Same example with WP_Query in single line :
1 | $custom_query = new WP_Query('posts_per_page=3&cat=-6,-9&order=ASC'); |
Notice, however, that with WP_Query, we don’t need the $query_string variable. In addition to using WP_Query to customize the default loop, we can also use it to create and customize multiple loops. Here is a basic example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | <?php // Loop 1 $first_query = new WP_Query('cat=-1'); // exclude category while($first_query->have_posts()) : $first_query->the_post(); ... endwhile; wp_reset_postdata(); // Loop 2 $second_query = new WP_Query('cat=-2'); // exclude category while($second_query->have_posts()) : $second_query->the_post(); ... endwhile; wp_reset_postdata(); // Loop 3 $third_query = new WP_Query('cat=-3'); // exclude category while($third_query->have_posts()) : $third_query->the_post(); ... endwhile; wp_reset_postdata(); ?> |
Each of these additional loops may be placed anywhere in your theme template – no need to line them up sequentially.
By setting up additional instances of WP_Query in your theme, you can create any number of multiple loops, and customize the output of each.
Loop with get_posts()
The easiest way to create multiple loops in the theme is to use get_posts(). Anywhere you need to display a quick, static set of posts, get_posts is the perfect choice. Think 10 recent posts in the sidebar, or 10 random posts in the footer. get_posts makes it easy. Here again is a query to exclude a specific category:
1 2 3 4 5 6 7 | <?php global $post; // required $args = array('category' => -6); // exclude category 6 $custom_posts = get_posts($args); foreach($custom_posts as $post) : setup_postdata($post); ... endforeach; ?> |
This code creates a loop of all posts except those in the excluded category. Like this, we can use other parameters also same as query_posts, WP_Query.
Notice, however, that get_posts requires the use of an array for the parameters. The format for multiple parameters looks like this (using our previous example):
1 | $args = array('numberposts'=>3, 'category'=>-6,-9, 'order'=>'ASC'); |
Use the get_posts() function to easily create additional, static loops anywhere in your theme.