Halloween DealsAmazon USHalloween week deals: useful picks before month-endAmazon US: current deals, useful picks and tech finds.Check DealsClean PCRecommendedOne scan can reveal what keeps slowing WindowsLook for cleanup and repair opportunities.Run ScanHalloween DealsAmazon USOctober picks are moving - compare before checkoutAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
VGSources
Blog

How to List Posts by Category in WordPress (Block Editor and PHP)

Display WordPress posts from one category using the Query Loop block, a secondary WP_Query, get_posts(), or the correct archive template. Includes category arguments, code, pagination guidance and fixes for common errors.
WorldWordPress Length13 min Posted Quest giverVGSources Team
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

For a visual, no-code list, add a Query Loop block and set its category filter. For a PHP template or landing page that needs precise control, create a secondary WP_Query. Use get_posts() for a short, non-paginated list, and do not use query_posts() to add a secondary section because it replaces the main query.

Choose the method that matches the page

WordPress can show posts from one category in several ways, but each method solves a different layout problem. Decide first whether the category should have its own canonical archive URL or whether the posts are one section inside another page.

As an Amazon Associate I earn from qualifying purchases.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Method Best for Category control Main caution
Query Loop block Block themes and editors who want a visual workflow Category filter in the block settings, plus controls for post type, order and item count The theme and editor determine the exact layout controls
WP_Query Custom PHP templates, landing pages and carefully styled sections Category slugs, IDs, multi-category inclusion and exclusions Call wp_reset_postdata() after the loop
get_posts() A small secondary list, such as five links in a sidebar Most normal query arguments, including category filters It is not the right choice for a full, paginated archive
Category/archive template A category URL that is the primary destination for that topic WordPress archive routing The available template depends on the theme

A category archive and an embedded list are not interchangeable. An archive is a destination users can navigate to and paginate through. An embedded list is a component on a page that may also contain a hero section, other categories or unrelated content.

Match common goals to the right tool

  • “How do I show posts from one category on a page?” Add a Query Loop to the page, or place a secondary WP_Query in the page template when the markup must be coded.
  • “How can I display category posts in a grid?” Use a Query Loop with its grid or column controls, then design the nested Post Template as a card. In PHP, output the card markup inside a secondary query.
  • “How do I list posts by category without a plugin?” The Query Loop, WP_Query, get_posts() and the built-in category archive are all core WordPress approaches.
  • “Should I use Query Loop or WP_Query?” Choose Query Loop for editor-managed presentation. Choose WP_Query when code must control the query arguments, HTML or placement.

List category posts with the Query Loop block

The Query Loop block is the simplest option when you are working in the block editor or a block theme. It creates the query and the presentation together, so you can change the category, order, number of posts and layout without editing PHP.

Set up the block

  1. Open the page in the WordPress editor. In a block theme, you can also open the Site Editor when the list belongs in a template or pattern.
  2. Insert a Query Loop block.
  3. Choose the post type. For a normal blog category, select the standard Post post type.
  4. Open the block settings and set the category filter. Select the category whose posts should appear.
  5. Choose a list or grid arrangement. The exact design controls depend on the active theme and editor version.
  6. Open the nested Post Template and add the fields readers need, such as Post Title, Featured Image, Excerpt, Date, Author, Categories and Read More.
  7. Set the number of posts and the ordering. If the category can contain more results than the first view, insert a Pagination block inside the Query Loop.
  8. Add a No Results section with a useful message. This prevents an empty category from leaving a blank area on the page.

The Query Loop’s controls apply to both the data and its display: you choose the post type and filters, then decide how many items to show and how they should be ordered. Post Template controls the repeated item, Pagination handles additional result pages, and No Results handles an empty result set.

Designing a category grid

For a grid, keep the repeated Post Template focused on a consistent card: a featured image, linked title, short excerpt and a read-more link. Set the number of columns using the layout controls exposed by your theme. If the theme does not offer the column setting you expect, the block can still query the correct category; the visual arrangement may require a different pattern or theme style.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

When several categories belong on one landing page, add one Query Loop block for each section and give each block its own category filter. For example, a page can place a News loop above a Tutorials loop without changing the site’s main query. Give every loop a heading and a No Results message so visitors understand which section is empty.

Decide whether the loop needs pagination

A short “latest from this category” section normally needs only an item count and a link to the full category archive. If visitors are expected to browse all matching posts on the page itself, add Pagination and make sure the loop is configured for enough results per page. Pagination belongs inside the Query Loop so it operates on that loop’s result set rather than on unrelated page content.

Use a secondary WP_Query in PHP

Use a new WP_Query when the list belongs in a custom template, a theme component or a landing page that needs PHP-level control. This creates a secondary query instead of replacing the page’s primary query.

Basic category query by slug

category_name expects the category’s slug, not the display name shown in the WordPress admin. The following example requests ten published posts from the news category and prints a title and excerpt for each result.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
<?php
$category_posts = new WP_Query([
    'post_type'      => 'post',
    'category_name'  => 'news',
    'posts_per_page' => 10,
]);

if ($category_posts->have_posts()) :
    while ($category_posts->have_posts()) :
        $category_posts->the_post();
        ?>
        <article>
            <h2><a href='<?php the_permalink(); ?>'><?php the_title(); ?></a></h2>
            <?php the_excerpt(); ?>
        </article>
        <?php
    endwhile;
endif;
wp_reset_postdata();

The loop checks for results, advances through the secondary query, and uses the normal template tags for each post. The final wp_reset_postdata() is essential: it restores the post object that the surrounding template was using before this loop ran.

Choose the right category argument

Argument Value Use it when
category_name A category slug, such as news You know the human-readable URL slug and want a readable query
cat A category ID An ID is more convenient; the documented behavior includes child categories
category__in An array of category IDs You want posts matching any listed category; the documented ID-list behavior does not include child categories
category__and An array of category IDs Every listed category must be assigned to the post
category__not_in An array of category IDs You need to exclude posts assigned to particular categories

Use only the argument that expresses the rule you actually need. A slug is not interchangeable with an ID: passing a category’s visible name to category_name can return no posts even when the category exists.

Examples of multi-category rules

Use an array with category__in when a section should include posts from any of several categories. Use category__and when every listed category must be present on the same post, such as content tagged for two required subjects. Add category__not_in when a broad query should omit particular categories. These ID-based arguments are distinct from category_name, which accepts one slug.

<?php
$category_posts = new WP_Query([
    'post_type'      => 'post',
    'category__in'   => [3, 7],
    'posts_per_page' => 10,
]);

Replace the example IDs with the IDs of the categories you actually intend to match. If the requirement is “this category and all of its children,” use the documented cat behavior rather than assuming that category__in will include descendants.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Controlling the result set

post_type limits the query to the content type you intend to display, while posts_per_page controls the number of results in that request. If the section is supposed to show public content, set an appropriate publication status rather than relying on an accidental default. The surrounding template should also decide whether it needs a pagination interface; a short promotional section and a complete archive have different requirements.

Reset the post context every time

Template tags such as the_title() and the_permalink() read the global post context. Calling the_post() inside a secondary query changes that context. Always place wp_reset_postdata() after the loop, including when the query returns no posts, so headings, sidebars and later template code continue to refer to the correct main post.

Where the PHP query belongs

Place the secondary query in the template or component that owns the section: for example, a landing-page template can render its heading, run the category query and print the cards in one place. Keep it separate from the page’s main loop. If the same component appears in several templates, keep its category argument explicit so a later edit does not accidentally inherit the current page’s category.

Use get_posts() for a small secondary list

get_posts() is useful when you need a compact list and do not need a full archive interface. It accepts WordPress query arguments, returns an array of post objects and does not replace the global main loop. A sidebar with five category links is a typical use.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
<?php
$category_posts = get_posts([
    'category_name' => 'news',
    'numberposts'   => 5,
    'post_status'   => 'publish',
]);

foreach ($category_posts as $post) :
    setup_postdata($post);
    ?>
    <a href='<?php the_permalink(); ?>'><?php the_title(); ?></a>
    <?php
endforeach;
wp_reset_postdata();

The call to setup_postdata() makes standard template tags work for each returned object. The reset at the end is still required because the loop temporarily changes the global post context.

Choose get_posts() when the list is intentionally small and self-contained. For a category page where visitors must move through many results, use the normal archive or a query designed for pagination instead of treating a short array as the entire archive.

Know its limits

A five-link sidebar and a full category archive have different jobs. get_posts() is convenient for the first job because you can iterate over the returned array directly. It is less suitable when readers need page-by-page navigation, a category heading and the complete result set. In that situation, use the category archive or a paginated query presentation.

Why query_posts() is the wrong tool for an embedded list

query_posts() also uses WP_Query, but it directly alters the main loop. That can interfere with the page’s original title, pagination, conditional checks and other template logic. Do not call it merely to append a category list to a page.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Create a separate WP_Query or use get_posts() for secondary content. If the actual requirement is to change the main category archive query, do that before the loop with the pre_get_posts hook and target the main query conditionally. This preserves the role of the archive’s primary query instead of replacing it from inside the template.

Category archive or embedded list?

Use the category archive when the category itself is the page’s subject. Visitors should be able to reach one stable URL, see the category’s primary heading and browse its results. In a classic theme, an archive can be rendered through archive.php. A custom post type can use an archive-{post_type}.php template. Whether those files are available and how much control they provide depends on the theme.

Use an embedded Query Loop or secondary WP_Query when the category is only one part of a broader page. A home page may show a few News posts, a Tutorials section and other content below them. In that case, the page’s main query should remain intact and each category section should be an independent component.

Requirement Preferred solution Reason
The category is the primary topic and needs a navigable URL Category archive WordPress archive routing supplies the page-level destination
A page contains several curated category sections Multiple Query Loop blocks or secondary WP_Query instances Each section can have its own filter, count and presentation
A sidebar needs a handful of links get_posts() It is a small separate list and does not replace the main loop
The archive’s main result rules must change pre_get_posts on the main query It changes the intended archive query without using query_posts() in the template

When a category archive is the better destination

An archive keeps navigation, heading and result browsing centered on the category. It is the natural choice when a visitor clicks a category link and expects to see that topic’s posts rather than a marketing page with several unrelated sections. An embedded list can still link to the archive so readers have a path to the rest of the category.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Troubleshoot an empty or incorrect category list

The query returns no posts

  • Check the category slug in category_name. The slug is the URL-friendly value, not necessarily the label displayed in the editor.
  • Confirm that the posts are assigned to that category and have the status your query requests, normally publish for a public list.
  • Verify post_type. A query limited to standard posts will not return a custom post type.
  • When using IDs, confirm that you selected the intended argument. cat and category__in have different documented behavior around child categories.
  • Check that the Query Loop filter is set on the loop itself and that you did not select a different post type while editing the block.

The list shows too few posts

  • Review posts_per_page in WP_Query, numberposts in get_posts() or the Query Loop’s item-count setting.
  • If the category can exceed the first result set, add Pagination to the Query Loop or use the site’s archive for complete browsing.
  • Make sure another filter, such as post type or publication status, is not narrowing the result unexpectedly.
  • Remember that a small get_posts() array is intentionally limited; increasing its count does not create archive navigation.

Posts after the list look wrong

  • Ensure every secondary loop ends with wp_reset_postdata().
  • Do not use query_posts() to build the component. Its alteration of the main loop can affect later template output.
  • If you changed the main archive query, use pre_get_posts conditionally and leave unrelated queries untouched.

The block displays a blank area

  • Open the Query Loop’s No Results section and add a message explaining that the category currently has no published posts.
  • Check that the category filter is applied to the Query Loop itself rather than only to a surrounding heading or group.
  • Confirm that the selected post type matches the content you expect to display.
  • Review the item count and ordering settings so the block is not configured in a way that hides the expected first results.

Practical selection checklist

  • Choose Query Loop when you want to configure the list in the editor and need a list or grid with built-in Post Template, ordering, count, Pagination and No Results controls.
  • Choose a secondary WP_Query when PHP must control the markup, category logic or placement in a custom template.
  • Choose get_posts() for a small, non-paginated set of related links.
  • Choose the category archive when the category is the page’s primary destination.
  • Use category slugs with category_name, IDs with the ID-based arguments, and reset post data after every custom loop.
  • Reserve query_posts() for no secondary-list use; change the main query through pre_get_posts when that is genuinely the requirement.

Frequently Asked Questions

How do I show posts from one category on a WordPress page?

Insert a Query Loop block, choose the Post post type, and set its category filter. In PHP, use a secondary WP_Query with category_name set to the category slug, then call wp_reset_postdata() after the loop.

How can I display category posts in a grid?

Use the Query Loop’s grid or column layout and design its Post Template with a featured image, title, excerpt and Read More block. A PHP template can print the same card structure inside a secondary WP_Query.

Can I list posts by category without a plugin?

Yes. The Query Loop block, category archives, WP_Query and get_posts() are built-in WordPress options.

Should I use Query Loop or WP_Query?

Use Query Loop when editors should manage the filter and layout visually. Use WP_Query when a template needs precise PHP control over category arguments, markup or placement.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

What is the difference between category_name and cat?

category_name accepts a category slug such as news. cat accepts a category ID and has documented behavior that includes child categories.

Why does my category query return no posts?

Check that category_name contains the URL slug rather than the display name, the posts are assigned to that category and published, and post_type matches the content you want.

Do I need wp_reset_postdata() after a category loop?

Yes. A secondary WP_Query or a get_posts() loop changes the temporary post context used by template tags. Reset it afterward so the surrounding template continues using the correct post.

When should I use a category archive instead of an embedded list?

Use the archive when the category is the page’s primary subject and needs a stable navigable URL with browsing and pagination. Use an embedded list when the category is one section within a broader page.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The Bottom Line

Use Query Loop for an editor-controlled list or grid, a secondary WP_Query for PHP-level control, and get_posts() for a short standalone list. Keep the category archive for the category’s main destination, reset post data after custom loops, and never use query_posts() to add an embedded section.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More quests from Patch Notes

  1. How to Set Up a RedM (RDR2) Server in 2026: License Key, txAdmin and server.cfg, Step by StepBlog11min
  2. Best RedM (RDR2) Server Hosting in 2026: Comparing Four Hosts on Slots, Memory and PriceBlog10min
  3. How to Host a Mindustry Server in 2026: server-release.jar, Port 6567 and the Commands That MatterBlog7min
Recommended PC Tool
Recommended PC Tool
Outdated Drivers Are Slowing You DownFree scan - exact matches
Windows Errors? Fix Them Before They SpreadFree repair scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.