Episode 27 of 32

Making a Custom Loop

Create custom WP_Query loops to display posts filtered by category, tag, custom fields, or other criteria.

Making a Custom Loop

The default WordPress Loop displays whatever posts WordPress has prepared for the current page. But sometimes you need to display specific posts — latest posts from a category, featured posts, or posts with certain custom fields. That's where WP_Query comes in.

Basic Custom Query

<?php
$args = array(
    'post_type'      => 'post',
    'posts_per_page' => 3,
    'post_status'    => 'publish',
);
$custom_query = new WP_Query($args);

if ($custom_query->have_posts()) :
    while ($custom_query->have_posts()) : $custom_query->the_post();
?>
    <article class="post-card">
        <h3><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h3>
        <?php the_excerpt(); ?>
    </article>
<?php
    endwhile;
    wp_reset_postdata();
else :
    echo '<p>No posts found.</p>';
endif;
?>

Important: wp_reset_postdata()

After every custom WP_Query, you must call wp_reset_postdata(). This restores the global $post variable so the rest of the page works correctly.

Filtering by Category

$args = array(
    'category_name'  => 'javascript',
    'posts_per_page' => 4,
);

// Or by category ID:
$args = array(
    'cat' => 5,
    'posts_per_page' => 4,
);

Filtering by Tag

$args = array(
    'tag' => 'beginner',
    'posts_per_page' => 4,
);

Filtering by Custom Field (Meta Query)

// Posts with a star_rating of 5
$args = array(
    'meta_key'   => 'star_rating',
    'meta_value' => '5',
    'posts_per_page' => -1,
);

// Posts with rating >= 4 (using meta_query)
$args = array(
    'meta_query' => array(
        array(
            'key'     => 'star_rating',
            'value'   => '4',
            'compare' => '>=',
            'type'    => 'NUMERIC',
        ),
    ),
);

Common WP_Query Parameters

ParameterWhat It DoesExample
post_typeType of content'post', 'page'
posts_per_pageNumber of posts (-1 for all)6
category_nameFilter by category slug'javascript'
tagFilter by tag slug'beginner'
orderbySort by field'date', 'title', 'rand'
orderSort direction'DESC', 'ASC'
meta_keyCustom field to filter/sort by'star_rating'
post__not_inExclude specific post IDsarray(1, 5, 12)

Practical Example: Featured Posts Section

<section class="featured-posts">
    <h2>Featured Articles</h2>
    <div class="post-grid">
        <?php
        $featured = new WP_Query(array(
            'meta_key'       => 'is_featured',
            'meta_value'     => 'yes',
            'posts_per_page' => 3,
            'orderby'        => 'date',
            'order'          => 'DESC',
        ));
        while ($featured->have_posts()) : $featured->the_post();
        ?>
            <article class="post-card featured">
                <?php the_post_thumbnail('medium_large'); ?>
                <h3><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h3>
                <?php the_excerpt(); ?>
            </article>
        <?php endwhile; wp_reset_postdata(); ?>
    </div>
</section>

Key Takeaways

  • WP_Query lets you fetch any posts with specific criteria
  • Always call wp_reset_postdata() after a custom query
  • Filter by category, tag, custom fields, or any combination
  • meta_query enables powerful filtering by custom field values
  • Use custom loops for featured sections, related posts, and homepage modules