iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
Antihost offers managed WordPress hosting with free migration, one-click staging and a 14-day free trial.
For a visual, no-code list, add a Query Loop block and set its category filter. For PHP templates, create a secondary WP_Query; use get_posts() for a short, separate list. Do not use query_posts() for an embedded list because it replaces the page’s main query.
Choose the method that matches the page
WordPress can show category posts in several fundamentally different ways. The right choice depends on whether you need an editor-managed block, a custom PHP layout, a small widget-like list, or the category’s canonical archive page.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
| Method | Best for | Category controls | Important limitation |
|---|---|---|---|
| Query Loop block | Block themes and visual editing | Category filter, post type, order, count, pagination and no-results settings | The exact controls and styling depend on the active theme and editor |
WP_Query |
Custom templates, landing pages and PHP-driven grids | Slug, ID, multiple-category inclusion and exclusion | Restore global post data after the loop |
get_posts() |
A small secondary list such as “latest news” | Most normal query arguments, including category filters | Not the right foundation for a full paginated archive |
| Category archive template | When the category itself is the page’s main subject | WordPress archive routing and the main query | Whether you can customize it directly depends on the theme |
Decide whether you need an archive or an embedded list
Use the category archive for a category’s primary destination
A category archive is the normal URL where visitors browse all posts assigned to a category. It is appropriate when someone arrives specifically to read that topic, and when the category page should own its title, description, navigation and pagination. In a classic theme, the archive may be rendered through archive.php. A custom post type can have a template such as archive-{post_type}.php. The exact template hierarchy and available editing controls are theme-dependent.
Embed a category list when it supports other page content
An embedded list belongs on a page that has a broader purpose: for example, a home page with separate sections for News and Tutorials, or a campaign page that places a curated category grid below introductory content. A Query Loop or secondary PHP query lets each section have its own heading, number of items and visual treatment without turning the entire page into a category archive.
#1 Best Overall
These are different navigation decisions, not merely two coding styles. Choose the archive when the category is the page’s main content; choose an embedded list when the category is one component of a larger layout.
List category posts without code using Query Loop
The Query Loop block is the simplest route for block themes and for editors who want to change the layout without editing PHP. It can query posts, filter them by category, display them as a list or grid, control ordering and item count, paginate longer results, and show a dedicated message when nothing matches.
PC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuteStep 1: Insert the block
- Open the page in the WordPress editor, or open the Site Editor when you are editing a template.
- Insert a Query Loop block where the category list should appear.
- Choose the post type. For a normal blog category, select posts; choose another type only when that content type supports the taxonomy you need.
Step 2: Apply the category filter
In the Query Loop settings, open the filters or query controls and select the category. Use the category’s displayed name in the picker; the block handles the underlying term selection for you. If the category does not appear, verify that it exists and that published posts are assigned to it.
Step 3: Pick a list or grid layout
Choose a list for a compact feed or a grid for cards. The selected pattern determines the initial structure, but you can edit the Post Template inside the Query Loop. Add or remove blocks such as Post Title, Featured Image, Excerpt, Date, Author, Categories and Read More. Keep the title linked so visitors can open the full post.
Step 4: Set count and ordering
Set how many posts should appear on each page and choose the order, such as newest first. A small number works well for a landing-page section; a larger number is more suitable for an archive-like page. Do not assume that displaying a fixed first page gives visitors access to older posts.
Step 5: Add pagination when the category continues
Insert the Query Loop’s Pagination block when the filtered category can contain more posts than the first page. Test the next and previous links on the front end, not only in the editor, because theme styles can affect their visibility and spacing.
Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Repair Windows errors before they cause bigger problems3Fix the driver behind crashes, sound loss and screen glitchesStep 6: Define the empty state
Inside the Query Loop, add a No Results section. Write a short message explaining that no published posts currently match the category, and provide a useful next action such as returning to the main blog. Without this section, an empty query can leave a confusing blank area.
Step 7: Check the front-end result
Preview the page at the screen sizes your audience uses. Confirm that long titles wrap cleanly, images have meaningful alternative text where appropriate, excerpts do not create uneven card heights, and pagination remains reachable by keyboard. Save only after checking the filtered result as a visitor would see it.
Build a category list with a secondary WP_Query
Use a new WP_Query when PHP must control the markup, query arguments or placement in a custom template. This is the standard approach for a landing page that needs a bespoke card grid, a fixed section heading or several independently filtered lists.
Basic category query by slug
category_name expects the category’s URL slug, not its human-readable display name. The following example requests ten published posts from the news category and prints a simple linked title and excerpt.
Rank #3
<?php
$category_posts = new WP_Query([
'post_type' => 'post',
'category_name' => 'news', // category slug
'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 query is separate from the page’s main loop, but calling the_post() changes the current post context while the custom loop runs. wp_reset_postdata() restores the surrounding template’s post context afterward, preventing later headings, links or metadata from accidentally referring to the last item in the category list.
Use IDs or multiple-category rules when slugs are not enough
WordPress provides several category arguments for different matching rules:
cataccepts one category ID. It includes posts in that category and follows WordPress’s documented child-category behavior.category__inaccepts an array of category IDs and matches posts in any listed category. The documented behavior does not automatically include child categories.category__andaccepts an array of IDs and requires a post to belong to every listed category.category__not_inaccepts an array of IDs and excludes posts assigned to those categories.
For example, an “either News or Tutorials” query can use category__in, while a “must be in both News and Tutorials” query needs category__and. If you use IDs, verify the term IDs in the dashboard or with WordPress’s term tools rather than substituting a category name.
Control status, type and volume explicitly
Set post_type to the content type you actually want. Use post_status when the query must be explicit about published content, especially in a template that could run in an administrative preview. Set posts_per_page to the number the design can support; an unrestricted query can make a page unnecessarily heavy.
Free tools Windows power users keep installed
One-click scans. No signup required.
Add pagination for a multi-page custom list
A secondary query does not automatically create navigable pages just because it has many results. Pass the current page into the query and render pagination around the custom loop:
Rank #4
<?php
$current_page = max(1, get_query_var('paged'), get_query_var('page'));
$category_posts = new WP_Query([
'post_type' => 'post',
'category_name' => 'news',
'posts_per_page' => 10,
'paged' => $current_page,
]);
if ($category_posts->have_posts()) :
while ($category_posts->have_posts()) :
$category_posts->the_post();
// Render each post here.
endwhile;
echo paginate_links([
'total' => $category_posts->max_num_pages,
'current' => $current_page,
]);
endif;
wp_reset_postdata();
?>
Keep the pagination URL and page heading understandable, and test links when the list has zero, one and several pages. If the list is only a short section on a larger landing page, a “View all News” link to the category archive is often clearer than embedding a second pagination system.
Use get_posts() for a small, separate list
get_posts() is convenient when you need a handful of items and do not need a full archive experience. It retrieves posts that match query arguments without replacing the global main loop, making it suitable for a sidebar, footer, related-content strip or a compact “latest from this category” section.
<?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 argument name is numberposts in this helper. Because the result is intended to be short and non-paginated, do not use it as a substitute for a category archive with hundreds of posts. As with a custom WP_Query loop, reset post data after calling setup_postdata().
Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Repair Windows errors before they cause bigger problemsFix Now →Keep the main query intact
Why query_posts() causes problems
query_posts() also uses WP_Query, but it directly alters the main loop. Calling it merely to add a category list can break the page’s original title, pagination, conditional tags, offsets and other template behavior. It can also produce confusing results when another part of the page expects the original query.
For secondary content, create a new WP_Query, call get_posts() for a small list, or use the existing main query. Do not overwrite the main query from inside a template just to change one section.
Best Value
Change an archive’s main query with pre_get_posts
If the real requirement is to alter the category archive itself—for example, changing how many posts the archive displays—use the pre_get_posts hook and target the main query conditionally. The condition should distinguish the front end and the main query before changing its arguments, so administrative screens and unrelated queries are not affected. This keeps the archive’s normal routing and pagination intact.
Make the output usable and maintainable
Use semantic, linkable post markup
Wrap each result in an <article> element, give it a heading, and link the title to the post permalink. If an image is included, use the featured-image block or WordPress’s image functions so the site’s responsive image behavior is preserved. Keep the clickable area large enough on touch screens and ensure focus styles remain visible.
Recommended Free Tools
Limit what each card loads
For a grid, a title, thumbnail and short excerpt are usually enough. Loading full post content for every card increases page size and can expose formatting that was designed for the single-post view. Set a deliberate item count and avoid querying fields that the design never prints.
Handle empty and unpublished states
Visitors only see published posts on the public site unless a preview or custom status is intentionally requested. A category with no published matches should have an explicit message in a Query Loop or a conditional branch in PHP. Do not leave an empty heading that suggests content failed to load.
Troubleshoot a category list that is empty or wrong
- Nothing appears: confirm that the category has published posts and that the selected post type is correct.
- The PHP filter returns zero posts: check that
category_namecontains the slug, not the display name. Slugs can differ in capitalization, punctuation and translated text. - ID matching is unexpected: decide whether the requirement is one category with
cat, any category in a list withcategory__in, all categories withcategory__and, or exclusions withcategory__not_in. Verify the IDs. - Only the first items are visible: set a suitable posts-per-page value and add Query Loop pagination or custom pagination for a multi-page result.
- Content elsewhere on the page is incorrect: check that a custom loop restores post data and that no template code is using
query_posts()for the secondary section. - The editor shows a blank area for an empty category: add and customize the Query Loop’s No Results section.
- The layout differs between editor and site: inspect the active theme’s Query Loop, Post Template and pagination styles; those controls can change the final spacing and card arrangement.
A practical decision guide
Choose Query Loop when editors own the page
Select Query Loop if the page is edited in blocks, the category filter is straightforward, and the team needs to change card fields or the number of posts without deploying code. It provides the fastest path to a list or grid with built-in pagination and an empty state.
Choose WP_Query when the template owns the design
Select a secondary WP_Query when you need custom HTML, several independent category sections, complex inclusion rules, a custom post type, or PHP-controlled pagination. Keep the query narrowly scoped and restore post data immediately after its loop.
Choose get_posts() when five or so links are all you need
Use get_posts() for a compact, non-paginated group such as five recent links in a sidebar or footer. It is simpler than managing a full query loop, but it is not intended to power the canonical archive for a large category.
Choose the archive when category navigation is the product
Use the normal category archive when visitors should browse that topic as a destination with its own URL, heading and pagination. Customize the relevant archive template or the main query rather than inserting a second list into an unrelated page.
Quick Recap
Final checklist before publishing
- The category filter points to the intended term and post type.
- The number of displayed posts matches the page’s purpose and performance budget.
- Longer categories have working pagination or a clear link to the archive.
- Each result has a descriptive, keyboard-accessible title link.
- An empty category produces a helpful message instead of a blank block.
- PHP loops restore the surrounding post context.
- The implementation does not overwrite the main query merely to create a secondary list.
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.

