
The WordPress loop is a list of all or limited number of post and page entries in database. It is the main part of each WordPress theme and core of every WordPress powered site. It cycles through posts that allow us to display them in any manner we want.

Before we start, let’s see how the heck we can structure this loop.
- Start the loop
- Do something in loop
- End the loop
The Loop
The simple example of WordPress loop is:
<?php if ( have_posts() ): while ( have_posts() ) : the_post(); ?>
<?php endwhile; endif; ?>
OR
<?php
if ( have_posts() ) {
while ( have_posts() ) {
the_post();
//
// Post Content here
//
} // end while
} // end if
?>
The above is a very simple loop but WordPress provides four ways to get the customized one.
All above looping techniques are pretty useful in various situations. These four loops can be used in simple loops, multiple loops as well as custom loops in your WordPress theme.
What we can display within loop
There are lots of things that we can display in the loop, such as post title, content, excerpt, post metadata etc. Some of them are given below:
- the_ID
- the_title
- the_time
- the_shortlink
- the_author
- the_category
- the_tags
- the_excerpt
- the_content
- next_post_link
- previous_post_link
- etc.
Let’s start using WordPress loop in different ways:
Default Loop
The WordPress default loop is as under that we already seen at the starting of article:
<?php if ( have_posts() ): while ( have_posts() ) : the_post(); ?>
// Display the Post
<?php endwhile; ?>
// Next/Previous navigation or numeric pagination
<?php else : ?>
// what to do if there is no any post/page? (Post not found)
<?php endif; ?>
This loop is only work with default post type called “post” and it is not able to modify global query. It displays certain number of posts that is specified from WordPress admin.
Using query_posts()
The query_posts()
is used to alter the main query that we’ve seen. It puts the main query to one side and put new query to another side. When we use this method then we must have to call wp_reset_query()
function to restore main query.
For example, if we want to display 5 posts on homepage instead of 10 latest posts.
global $query_string;
query_posts( $query_string . 'posts_per_page=5' );
Kindly note that, if we remove $query_string
variable from the query_posts()
then it will remove the default query and replaces it with your given variable. It means paging won’t work and some other stuff, so remove it if you know what you’re doing otherwise you’ll do something smart with your website.(actually i doubt it)
Basic usage
<?php
// The Query
query_posts( $args );
// The Loop
while ( have_posts() ) : the_post();
// Display main post content
endwhile;
// Reset Query
wp_reset_query();
?>
Using WP_Query()
The WP_Query(), provide full control over customization of loops. It is used to modify default loop, it is similar to query_posts()
.
Let’s see the query that fetches multiple custom post type:
$wp_query = new WP_Query( 'post_type[]=post_type_1&post_type[]=post_type_2' );
Excluding specific category from being displayed:
$wp_query = new WP_Query( 'cat=-10' ); // It’ll exclude category 9.
Basic usage
<?php
$wp_query = new WP_Query( 'post_type[]=post_type_1&post_type[]=post_type_2&cat=-10' );
while($wp_query->have_posts()) : $wp_query->the_post();
// Main post content
$wp_query->the_post();
endwhile;
// Restore original data
wp_reset_postdata();
?>
Note: If you use the_post()
with your query, you need to run wp_reset_postdata()
to restore original post data.
Using get_posts()
This is the best way to create multiple loops in WordPress theme. When you want to display post other than homepage like custom page templates, get_posts() is the best choise.
Basic usage
<?php
global $post; // compulsory
$args = array( 'posts_per_page' => 5 ); // display 5 posts per page
$posts = get_posts($args);
foreach($posts as $post) : setup_postdata($post);
// Post content
endforeach;
?>
You can use get_posts()
function to create additional loops anywhere in your theme. It uses the same parameter as query_posts()
, we can use it in sidebar or footer to create recent post widget or something else.