Query Functions
Functions for querying posts, managing The Loop, and checking query conditions.
Source: wp-includes/query.php
Loop Functions
have_posts()
Determines whether current WordPress query has posts to loop over.
function have_posts(): bool
Returns: true if posts are available, false if end of the loop.
Usage:
if ( have_posts() ) {
while ( have_posts() ) {
the_post();
// Display post
}
}
Notes:
- Calls
loop_endaction when loop completes - Calls
loop_no_resultsaction if no posts found - Automatically rewinds posts when finished
the_post()
Iterates the post index in the loop and sets up global post data.
function the_post(): void
Effects:
- Advances
$wp_query->current_post - Sets global
$postto current post - Calls
setup_postdata()to populate globals - Fires
loop_startaction on first iteration
Usage:
while ( have_posts() ) {
the_post();
the_title();
the_content();
}
rewind_posts()
Rewind the loop posts to the beginning.
function rewind_posts(): void
Usage:
// Loop through posts twice
while ( have_posts() ) { the_post(); /* first pass */ }
rewind_posts();
while ( have_posts() ) { the_post(); /* second pass */ }
in_the_loop()
Determines whether the caller is inside The Loop.
function in_the_loop(): bool
Returns: true if inside loop, false otherwise.
Usage:
if ( in_the_loop() ) {
// Safe to use template tags like the_title()
}
Since: 2.0.0
setup_postdata()
Sets up global post data for template tags.
function setup_postdata( WP_Post|object|int $post ): bool
Parameters:
$post— Post object or ID
Returns: true when finished.
Sets Globals:
$id— Post ID$authordata— Author user object$currentday— Day in DD.MM.YY format$currentmonth— Month number$page— Current page for paginated posts$pages— Array of post content pages$multipage— Whether post has multiple pages$more— Whether to show full content$numpages— Number of pages
Usage:
$posts = get_posts( $args );
foreach ( $posts as $post ) {
setup_postdata( $post );
the_title();
the_excerpt();
}
wp_reset_postdata();
Since: 1.5.0, 4.4.0 (added post ID support)
generate_postdata()
Generates post data array without setting globals.
function generate_postdata( WP_Post|object|int $post ): array|false
Parameters:
$post— Post object or ID
Returns: Array of post elements or false on failure.
Array Keys:
id,authordata,currentday,currentmonthpage,pages,multipage,more,numpages
Since: 5.2.0
Query Variable Functions
get_query_var()
Retrieves the value of a query variable.
function get_query_var( string $query_var, mixed $default_value = '' ): mixed
Parameters:
$query_var— Variable key to retrieve$default_value— Value if variable not set (default:'')
Usage:
$paged = get_query_var( 'paged', 1 );
$cat_id = get_query_var( 'cat' );
$search_term = get_query_var( 's' );
Since: 1.5.0, 3.9.0 (added $default_value)
set_query_var()
Sets the value of a query variable.
function set_query_var( string $query_var, mixed $value ): void
Parameters:
$query_var— Query variable key$value— Query variable value
Usage:
set_query_var( 'posts_per_page', 20 );
Note: Only affects current request; doesn’t persist.
Since: 2.2.0
get_queried_object()
Retrieves the currently queried object.
function get_queried_object(): WP_Term|WP_Post_Type|WP_Post|WP_User|null
Returns: Depends on context:
- Category/tag/taxonomy archive →
WP_Term - Post type archive →
WP_Post_Type - Single post/page →
WP_Post - Author archive →
WP_User - Otherwise →
null
Usage:
$obj = get_queried_object();
if ( $obj instanceof WP_Term ) {
echo $obj->name;
}
Since: 3.1.0
get_queried_object_id()
Retrieves the ID of the currently queried object.
function get_queried_object_id(): int
Returns: ID of queried object, or 0 if none.
Usage:
$term_id = get_queried_object_id(); // On taxonomy archive
$post_id = get_queried_object_id(); // On singular
Since: 3.1.0
Query Execution Functions
query_posts()
Sets up The Loop with query parameters. Avoid using this function.
function query_posts( array|string $query ): WP_Post[]|int[]
Parameters:
$query— Array or query string of WP_Query arguments
Returns: Array of post objects or IDs.
⚠️ Warning: This function:
- Completely overrides the main query
- Breaks pagination
- Causes conditional tag issues
- Should never be used in themes or plugins
Use Instead:
// For modifying main query:
add_action( 'pre_get_posts', function( $query ) {
if ( $query->is_main_query() ) {
$query->set( 'posts_per_page', 5 );
}
} );
// For secondary queries:
$custom_query = new WP_Query( $args );
Since: 1.5.0
wp_reset_query()
Destroys the previous query and restores the original.
function wp_reset_query(): void
Effects:
- Restores
$wp_queryto$wp_the_query - Calls
wp_reset_postdata()
Usage: Only after query_posts(), which you shouldn’t use.
Since: 2.3.0
wp_reset_postdata()
Restores the global $post to the current post in the main query.
function wp_reset_postdata(): void
Usage:
$my_query = new WP_Query( $args );
while ( $my_query->have_posts() ) {
$my_query->the_post();
// ...
}
wp_reset_postdata(); // Restore main query's $post
Since: 3.0.0
Conditional Tags
All conditional tags check against the global $wp_query object.
is_main_query()
Determines whether the query is the main query.
function is_main_query(): bool
⚠️ Important: Inside pre_get_posts, use the method version:
add_action( 'pre_get_posts', function( $query ) {
if ( $query->is_main_query() ) { // Use $query, not is_main_query()
// ...
}
} );
Since: 3.3.0
is_singular()
Determines whether the query is for a single post (post, page, attachment, CPT).
function is_singular( string|string[] $post_types = '' ): bool
Parameters:
$post_types— Post type(s) to check against (optional)
Usage:
is_singular(); // Any single post
is_singular( 'post' ); // Single blog post
is_singular( 'product' ); // Single product
is_singular( array( 'post', 'page' ) );
Since: 1.5.0
is_single()
Determines whether the query is for an existing single post.
function is_single( int|string|int[]|string[] $post = '' ): bool
Parameters:
$post— Post ID, title, slug, or array (optional)
Note: Works for posts and custom post types, excludes pages and attachments.
Usage:
is_single(); // Any single post
is_single( 15 ); // Post ID 15
is_single( 'hello-world' ); // Post with slug
Since: 1.5.0
is_page()
Determines whether the query is for an existing single page.
function is_page( int|string|int[]|string[] $page = '' ): bool
Parameters:
$page— Page ID, title, slug, path, or array (optional)
Usage:
is_page(); // Any page
is_page( 42 ); // Page ID 42
is_page( 'about' ); // Page with slug 'about'
is_page( 'company/about' ); // Page path
is_page( array( 'about', 'contact' ) );
Since: 1.5.0
is_attachment()
Determines whether the query is for an existing attachment page.
function is_attachment( int|string|int[]|string[] $attachment = '' ): bool
Since: 2.0.0
is_archive()
Determines whether the query is for an existing archive page.
function is_archive(): bool
Returns: true for category, tag, author, date, CPT archive, or custom taxonomy archive.
Since: 1.5.0
is_category()
Determines whether the query is for a category archive.
function is_category( int|string|int[]|string[] $category = '' ): bool
Parameters:
$category— Category ID, name, slug, or array (optional)
Since: 1.5.0
is_tag()
Determines whether the query is for a tag archive.
function is_tag( int|string|int[]|string[] $tag = '' ): bool
Since: 2.3.0
is_tax()
Determines whether the query is for a custom taxonomy archive.
function is_tax( string|string[] $taxonomy = '', int|string|int[]|string[] $term = '' ): bool
Parameters:
$taxonomy— Taxonomy slug(s) (optional)$term— Term ID, name, slug, or array (optional)
Note: Returns false for category and tag archives (use is_category() or is_tag()).
Usage:
is_tax(); // Any custom taxonomy
is_tax( 'genre' ); // 'genre' taxonomy
is_tax( 'genre', 'rock' ); // 'rock' term in 'genre'
is_tax( 'genre', array( 'rock', 'pop' ) );
Since: 2.5.0
is_post_type_archive()
Determines whether the query is for a post type archive.
function is_post_type_archive( string|string[] $post_types = '' ): bool
Since: 3.1.0
is_author()
Determines whether the query is for an author archive.
function is_author( int|string|int[]|string[] $author = '' ): bool
Parameters:
$author— User ID, nickname, nicename, or array (optional)
Since: 1.5.0
is_date()
Determines whether the query is for any date archive.
function is_date(): bool
Since: 1.5.0
is_year()
Determines whether the query is for a year archive.
function is_year(): bool
Since: 1.5.0
is_month()
Determines whether the query is for a month archive.
function is_month(): bool
Since: 1.5.0
is_day()
Determines whether the query is for a day archive.
function is_day(): bool
Since: 1.5.0
is_time()
Determines whether the query is for a specific time.
function is_time(): bool
Since: 1.5.0
is_home()
Determines whether the query is for the blog homepage.
function is_home(): bool
Note: This is the "Posts page", not necessarily the front page. If a static page is set as the front page, is_home() is true on the posts page.
Since: 1.5.0
is_front_page()
Determines whether the query is for the site front page.
function is_front_page(): bool
Returns: true for:
- Posts page when "Front page displays" is set to "Your latest posts"
- Static page when set as "Front page"
Since: 2.5.0
is_search()
Determines whether the query is for a search.
function is_search(): bool
Since: 1.5.0
is_feed()
Determines whether the query is for a feed.
function is_feed( string|string[] $feeds = '' ): bool
Parameters:
$feeds— Feed type(s) to check (optional):'rss2','atom','rss','rdf'
Since: 1.5.0
is_comment_feed()
Determines whether the query is for a comments feed.
function is_comment_feed(): bool
Since: 3.0.0
is_404()
Determines whether the query is a 404 (returns no results).
function is_404(): bool
Since: 1.5.0
is_paged()
Determines whether the query is for a paged result (not page 1).
function is_paged(): bool
Since: 1.5.0
is_preview()
Determines whether the query is for a post/page preview.
function is_preview(): bool
Since: 2.0.0
is_trackback()
Determines whether the query is for a trackback endpoint.
function is_trackback(): bool
Since: 1.5.0
is_robots()
Determines whether the query is for robots.txt.
function is_robots(): bool
Since: 2.1.0
is_favicon()
Determines whether the query is for favicon.ico.
function is_favicon(): bool
Since: 5.4.0
is_embed()
Determines whether the query is for an embedded post.
function is_embed(): bool
Since: 4.4.0
is_privacy_policy()
Determines whether the query is for the Privacy Policy page.
function is_privacy_policy(): bool
Since: 5.2.0
Comment Loop Functions
have_comments()
Determines whether current query has comments to loop over.
function have_comments(): bool
Since: 2.2.0
the_comment()
Iterates comment index and sets up global comment data.
function the_comment(): void
Usage:
if ( have_comments() ) {
while ( have_comments() ) {
the_comment();
comment_author();
comment_text();
}
}
Since: 2.2.0
Redirect Functions
wp_old_slug_redirect()
Redirects old slugs to the correct permalink.
function wp_old_slug_redirect(): void
Hooks:
old_slug_redirect_post_id— Filter the redirect post IDold_slug_redirect_url— Filter the redirect URL
Since: 2.1.0