WP_Query Generator
Build WP_Query arguments with post type, ordering, taxonomy and meta conditions, dates and pagination, then copy the loop.
<?php
/**
* Queries "post" ordered by date DESC.
*/
$args = array(
'post_type' => 'post',
'post_status' => 'publish',
'posts_per_page' => 10,
'orderby' => 'date',
'order' => 'DESC',
'paged' => max( 1, (int) get_query_var( 'paged' ) ),
'ignore_sticky_posts' => true,
);
$query = new WP_Query( $args );
if ( $query->have_posts() ) {
while ( $query->have_posts() ) {
$query->the_post();
the_title( '<h2>', '</h2>' );
}
// Restores the global $post so the rest of the page keeps working.
wp_reset_postdata();
}
Output is valid and updates as you type.
Fix the highlighted fields to update the output.
Set the post type, ordering and any taxonomy, meta or date conditions you need, and the generator writes the $args array plus the loop that goes with it. Everything is assembled in your browser, so nothing you type is sent anywhere.
How to use
- Pick the post type and status.
anycovers every status except trash and auto-draft. - Set how many posts a page should load. Leave paging on for archives; it reads the page number from the URL.
- Add taxonomy rows to restrict the query to terms, and meta rows to filter on custom fields.
- Choose the ordering. If you order by
meta_valueormeta_value_num, fill in the meta key to sort on. - Copy the snippet into a template, or download it and include it from your plugin.
Example
A shop lists hardback books over £20, newest first, 24 to a page, in the sci-fi and fantasy genres. The generator writes the tax_query with its relation, the meta_query comparison cast as NUMERIC, and the date bounds:
$args = array(
'post_type' => 'book',
'posts_per_page' => 24,
'orderby' => 'meta_value_num',
'order' => 'ASC',
'meta_key' => 'price',
'tax_query' => array(
'relation' => 'OR',
array(
'taxonomy' => 'genre',
'field' => 'slug',
'terms' => array_map( 'trim', explode( ',', 'sci-fi, fantasy' ) ),
'operator' => 'IN',
),
),
'paged' => max( 1, (int) get_query_var( 'paged' ) ),
'ignore_sticky_posts' => true,
);
The loop below it calls wp_reset_postdata() once it finishes, which puts the global $post back the way the rest of the page expects it.
Pitfalls
posts_per_page => -1loads every matching row into memory. It is fine in a one-off script and a problem on a page a visitor can reach.- Setting an offset turns paging off. WordPress ignores
pagedwhileoffsetis set, so pick one. no_found_rowsskips the count that pagination links are built from. Turn it on only for queries you never page.- Meta comparisons are not indexed. A
meta_queryon a large table is the usual reason a listing page gets slow. wp_reset_postdata()belongs after every secondary loop. Without it, the template around your loop starts reading the wrong post.- Ordering by
randcannot be cached and re-sorts the whole result set on each request. - Term slugs are matched, not names:
fieldis set toslug, so pass what appears in the URL.
Compatibility
Written for WordPress 4.4 and later, where WP_Query accepts the tax_query, meta_query and date_query shapes used here. ignore_sticky_posts and no_found_rows are older still. The generated code runs on PHP 7.0 and later, and the tool itself runs entirely in a current browser, with no network request while you configure it.
Frequently asked questions
Should I use WP_Query or get_posts()?
get_posts() wraps WP_Query and returns an array of post objects, which suits a quick list. Use WP_Query when you want the loop, pagination or the found-posts count.Why does my query ignore the page number?
offset has a value, so remove it and let paged do the work.How do I query several post types at once?
'post_type' to an array, such as array( 'post', 'book' ). The rest of the arguments work unchanged.Do I need to reset anything after the loop?
wp_reset_postdata() for you, which restores the main query’s current post.Can I use this for the main query on an archive?
pre_get_posts callback instead, or the page runs two queries and paginates the wrong one.