WP_Query Class

The main WordPress query class. Handles post retrieval, The Loop, and query state.

Source: wp-includes/class-wp-query.php
Since: 1.5.0

Basic Usage

$query = new WP_Query( array(
    'post_type'      => 'post',
    'posts_per_page' => 10,
    'category_name'  => 'news',
) );

if ( $query->have_posts() ) {
    while ( $query->have_posts() ) {
        $query->the_post();
        the_title();
        the_content();
    }
    wp_reset_postdata();
}

Properties

Query State

Property Type Description
$query array Original query vars as passed
$query_vars array Parsed and filled query vars
$request string SQL query string

Results

Property Type Description
$posts `WP_Post[] int[]`
$post `WP_Post null`
$post_count int Number of posts in current page
$found_posts int Total matching posts (all pages)
$max_num_pages int Number of pages
$current_post int Index of current post (-1 before loop)

Queried Object

Property Type Description
$queried_object `WP_Term WP_Post_Type
$queried_object_id int ID of queried object

Loop State

Property Type Description
$in_the_loop bool Whether currently in the loop
$before_loop bool Whether before the loop has started (since 6.3.0)

Query Type Flags

Property Description
$is_single Single post (not page or attachment)
$is_page Single page
$is_attachment Single attachment
$is_singular Any single post/page/attachment
$is_preview Post preview
$is_archive Any archive page
$is_category Category archive
$is_tag Tag archive
$is_tax Custom taxonomy archive
$is_author Author archive
$is_date Any date archive
$is_year Year archive
$is_month Month archive
$is_day Day archive
$is_time Time archive
$is_post_type_archive Post type archive
$is_home Blog home (posts page)
$is_front_page() Site front page (method, not property)
$is_privacy_policy Privacy policy page
$is_search Search results
$is_feed Feed request
$is_comment_feed Comments feed
$is_trackback Trackback endpoint
$is_paged Paginated (page 2+)
$is_admin Admin request
$is_404 No results found
$is_embed Embedded post
$is_robots robots.txt request
$is_favicon favicon.ico request
$is_posts_page Page assigned as posts page

Sub-Query Objects

Property Type Description
$tax_query `WP_Tax_Query null`
$meta_query `WP_Meta_Query false`
$date_query `WP_Date_Query false`

Comments

Property Type Description
$comments WP_Comment[] Comments for current post
$comment WP_Comment Current comment in loop
$comment_count int Number of comments
$current_comment int Current comment index
$max_num_comment_pages int Number of comment pages

Query Variables Reference

Post Selection

By ID

Variable Type Description
p int Post ID
post__in int[] Array of post IDs to include
post__not_in int[] Array of post IDs to exclude
page_id int Page ID
// Single post by ID
'p' => 42

// Multiple specific posts
'post__in' => array( 1, 2, 3 )

// Exclude posts
'post__not_in' => array( 10, 20 )

By Slug/Name

Variable Type Description
name string Post slug
pagename string Page slug (supports hierarchy: parent/child)
post_name__in string[] Array of post slugs
title string Exact post title match
// By slug
'name' => 'hello-world'

// By page path
'pagename' => 'about/team'

// Multiple slugs
'post_name__in' => array( 'hello', 'world' )

Post Type & Status

Variable Type Description
post_type `string string[]`
post_status `string string[]`

Post Type Values:

  • 'post' — Blog posts
  • 'page' — Pages
  • 'attachment' — Media
  • 'revision' — Revisions
  • 'nav_menu_item' — Menu items
  • 'any' — All types except revisions and types with exclude_from_search = true
  • Custom post type slugs

Post Status Values:

  • 'publish' — Published
  • 'pending' — Pending review
  • 'draft' — Draft
  • 'auto-draft' — Auto-draft
  • 'future' — Scheduled
  • 'private' — Private
  • 'inherit' — Inherits parent (attachments)
  • 'trash' — Trashed
  • 'any' — All except trash and auto-draft
// Multiple post types
'post_type' => array( 'post', 'page', 'product' )

// Multiple statuses
'post_status' => array( 'publish', 'private' )

Pagination

Variable Type Description
posts_per_page int Posts per page. -1 for all.
posts_per_archive_page int Posts per page on archives
nopaging bool Disable pagination
paged int Page number
offset int Number of posts to skip
page int Page number for static front page
// 10 posts per page, page 2
'posts_per_page' => 10,
'paged' => 2

// Skip first 5 posts
'offset' => 5

// All posts, no pagination
'posts_per_page' => -1
// or
'nopaging' => true

Category Parameters

Variable Type Description
cat `int string`
category_name string Category slug (includes children)
category__in int[] Category IDs (no children)
category__not_in int[] Exclude category IDs
category__and int[] Posts in ALL listed categories
// By category ID
'cat' => 5

// Multiple categories (OR)
'cat' => '2,6,17'

// Exclude category
'cat' => '-12'

// By slug
'category_name' => 'news'

// Posts in ALL categories
'category__and' => array( 2, 6 )

// Posts in ANY category (no children)
'category__in' => array( 2, 6 )

Tag Parameters

Variable Type Description
tag string Tag slug(s). Comma = OR, plus = AND
tag_id int Tag ID
tag__in int[] Tag IDs (OR)
tag__not_in int[] Exclude tag IDs
tag__and int[] Posts with ALL tags
tag_slug__in string[] Tag slugs (OR)
tag_slug__and string[] Tag slugs (AND)
// Single tag
'tag' => 'bread'

// Multiple tags (OR)
'tag' => 'bread,butter'

// Multiple tags (AND)
'tag' => 'bread+butter'

// By tag IDs
'tag__in' => array( 37, 47 )

// All tags required
'tag__and' => array( 37, 47 )

Taxonomy Parameters (tax_query)

Variable Type Description
tax_query array Complex taxonomy query

tax_query Structure:

'tax_query' => array(
    'relation' => 'AND', // 'AND' or 'OR' between clauses
    array(
        'taxonomy'         => 'genre',      // Taxonomy name
        'field'            => 'slug',       // 'term_id', 'slug', 'name', or 'term_taxonomy_id'
        'terms'            => array( 'action', 'comedy' ),
        'operator'         => 'IN',         // 'IN', 'NOT IN', 'AND', 'EXISTS', 'NOT EXISTS'
        'include_children' => true,         // Include children terms
    ),
    array(
        'taxonomy' => 'actor',
        'field'    => 'term_id',
        'terms'    => array( 103, 115 ),
    ),
)

Operators:

  • 'IN' — Match any term (default)
  • 'NOT IN' — Exclude posts with these terms
  • 'AND' — Match ALL terms
  • 'EXISTS' — Has any term in taxonomy
  • 'NOT EXISTS' — Has no terms in taxonomy

Author Parameters

Variable Type Description
author `int string`
author_name string Author nicename (slug)
author__in int[] Author IDs to include
author__not_in int[] Author IDs to exclude
// By author ID
'author' => 1

// Multiple authors
'author' => '1,2,3'

// Exclude author
'author' => '-1'

// By nicename
'author_name' => 'john-doe'

// Multiple authors
'author__in' => array( 1, 5, 12 )

Date Parameters

Variable Type Description
year int Four-digit year
monthnum int Month (1-12)
day int Day of month (1-31)
w int Week of year (0-53)
hour int Hour (0-23)
minute int Minute (0-59)
second int Second (0-59)
m int YearMonth (e.g., 202301)
date_query array Complex date query
// Posts from January 2023
'year' => 2023,
'monthnum' => 1

// Combined format
'm' => 202301

// Complex date query
'date_query' => array(
    array(
        'after'     => 'January 1st, 2023',
        'before'    => 'December 31st, 2023',
        'inclusive' => true,
    ),
)

See class-wp-date-query.md for complete date_query documentation.

Meta (Custom Field) Parameters

Variable Type Description
meta_key string Custom field key
meta_value string Custom field value
meta_compare string Comparison operator
meta_type string Data type for CAST
meta_query array Complex meta query

Simple Meta Query:

// Posts with specific meta value
'meta_key'   => 'color',
'meta_value' => 'blue'

// Numeric comparison
'meta_key'     => 'price',
'meta_value'   => 100,
'meta_compare' => '>=',
'meta_type'    => 'NUMERIC'

Complex meta_query:

'meta_query' => array(
    'relation' => 'AND',
    array(
        'key'     => 'color',
        'value'   => 'blue',
        'compare' => '=',
    ),
    'price_clause' => array(  // Named clause for ordering
        'key'     => 'price',
        'value'   => array( 20, 100 ),
        'type'    => 'NUMERIC',
        'compare' => 'BETWEEN',
    ),
),
'orderby' => 'price_clause' // Order by named clause

Compare Operators:

  • '=', '!=' — Equal, not equal
  • '>', '>=', '<', '<=' — Numeric comparison
  • 'LIKE', 'NOT LIKE' — Pattern matching
  • 'IN', 'NOT IN' — Value in array
  • 'BETWEEN', 'NOT BETWEEN' — Range
  • 'EXISTS', 'NOT EXISTS' — Key exists
  • 'REGEXP', 'NOT REGEXP', 'RLIKE' — Regular expression

Type Values:

  • 'NUMERIC', 'DECIMAL', 'SIGNED', 'UNSIGNED'
  • 'CHAR', 'BINARY'
  • 'DATE', 'DATETIME', 'TIME'

Search Parameters

Variable Type Description
s string Search keyword(s)
search_columns string[] Columns to search
sentence bool Search as exact phrase
exact bool Exact match (no wildcards)
// Basic search
's' => 'hello world'

// Exclude terms (prefix with -)
's' => 'pillow -sofa'

// Search specific columns
's' => 'hello',
'search_columns' => array( 'post_title', 'post_excerpt' )

// Exact phrase
's' => 'hello world',
'sentence' => true

Search Columns:

  • 'post_title'
  • 'post_excerpt'
  • 'post_content'

Ordering Parameters

Variable Type Description
orderby `string array`
order string 'ASC' or 'DESC'

orderby Values:

Value Description
'none' No order
'ID' Post ID
'author' Author ID
'title' Post title
'name' Post slug
'type' Post type
'date' Post date (default)
'modified' Last modified date
'parent' Parent post ID
'rand' Random
'RAND(x)' Random with seed
'comment_count' Number of comments
'relevance' Search relevance
'menu_order' Menu order
'meta_value' Meta value (requires meta_key)
'meta_value_num' Numeric meta value
'post__in' Preserve post__in order
'post_name__in' Preserve post_name__in order
'post_parent__in' Preserve post_parent__in order
// Single orderby
'orderby' => 'title',
'order'   => 'ASC'

// Multiple orderby
'orderby' => array(
    'menu_order' => 'ASC',
    'title'      => 'ASC',
)

// Order by meta
'meta_key' => 'price',
'orderby'  => 'meta_value_num',
'order'    => 'ASC'

// Preserve post__in order
'post__in' => array( 5, 2, 8 ),
'orderby'  => 'post__in'

// Random with seed (for consistent pagination)
'orderby' => 'RAND(123)'

Parent/Hierarchy Parameters

Variable Type Description
post_parent int Parent post ID. 0 for top-level.
post_parent__in int[] Parent IDs to include
post_parent__not_in int[] Parent IDs to exclude
// Children of post 10
'post_parent' => 10

// Top-level pages only
'post_type'   => 'page',
'post_parent' => 0

// Children of multiple parents
'post_parent__in' => array( 10, 20 )

Password Parameters

Variable Type Description
has_password bool true for protected, false for not
post_password string Posts with specific password
// Only password-protected posts
'has_password' => true

// Only non-protected posts
'has_password' => false

// Specific password
'post_password' => 'mypassword'

Comment Parameters

Variable Type Description
comment_status string 'open' or 'closed'
ping_status string 'open' or 'closed'
comment_count `int array`
comments_per_page int Comments per page
// Posts with comments open
'comment_status' => 'open'

// Posts with exact comment count
'comment_count' => 10

// Posts with more than 5 comments
'comment_count' => array(
    'value'   => 5,
    'compare' => '>'
)

Permission Parameters

Variable Type Description
perm string Permission check: 'readable' or 'editable'
// Only posts current user can read
'perm' => 'readable'

MIME Type (Attachments)

Variable Type Description
post_mime_type `string string[]`
// Only images
'post_type'      => 'attachment',
'post_status'    => 'inherit',
'post_mime_type' => 'image'

// Specific types
'post_mime_type' => array( 'image/jpeg', 'image/png' )

Cache Control

Variable Type Default Description
cache_results bool true Cache post information
update_post_meta_cache bool true Prime meta cache
update_post_term_cache bool true Prime term cache
update_menu_item_cache bool false Prime menu item cache
lazy_load_term_meta bool (varies) Lazy-load term meta
// Optimized query (no extra queries)
'cache_results'          => true,
'update_post_meta_cache' => false, // Don't need meta
'update_post_term_cache' => false, // Don't need terms

Miscellaneous

Variable Type Description
fields string Return format: '', 'ids', or 'id=>parent'
no_found_rows bool Skip counting total rows
suppress_filters bool Bypass filters
ignore_sticky_posts bool Ignore sticky post handling
menu_order int Specific menu order value
// Return only IDs (fast)
'fields' => 'ids'

// Return ID => parent mapping
'fields' => 'id=>parent'

// Skip SQL_CALC_FOUND_ROWS (faster when not paginating)
'no_found_rows' => true

// Bypass all filters
'suppress_filters' => true

// Don't put stickies first
'ignore_sticky_posts' => true

Methods

Constructor

public function __construct( string|array $query = '' )

Creates new query. If $query provided, immediately runs query().


Core Methods

query()

public function query( string|array $query ): WP_Post[]|int[]

Sets up the query and retrieves posts.

Parameters:

  • $query — Query string or array

Returns: Array of posts or post IDs.


get_posts()

public function get_posts(): WP_Post[]|int[]

Retrieves posts based on current query variables. Called internally by query().


parse_query()

public function parse_query( string|array $query = '' ): void

Parses query string and sets query type flags.


Loop Methods

have_posts()

public function have_posts(): bool

Check if more posts available. Fires loop_end and loop_no_results actions.


the_post()

public function the_post(): void

Advances to next post, sets up globals. Fires loop_start on first call.


rewind_posts()

public function rewind_posts(): void

Resets loop to beginning.


next_post()

public function next_post(): WP_Post

Returns next post in loop (internal use).


Comment Loop Methods

have_comments()

public function have_comments(): bool

Check if more comments available.


the_comment()

public function the_comment(): void

Advances to next comment.


rewind_comments()

public function rewind_comments(): void

Resets comment loop.


Getters/Setters

get()

public function get( string $query_var, mixed $default_value = '' ): mixed

Retrieves query variable value.


set()

public function set( string $query_var, mixed $value ): void

Sets query variable value.


get_queried_object()

public function get_queried_object(): WP_Term|WP_Post_Type|WP_Post|WP_User|null

Returns the main queried object based on query type.


get_queried_object_id()

public function get_queried_object_id(): int

Returns ID of queried object, or 0.


Post Data Methods

setup_postdata()

public function setup_postdata( WP_Post|object|int $post ): true

Sets up global post data. Fires the_post action.


generate_postdata()

public function generate_postdata( WP_Post|object|int $post ): array|false

Generates postdata array without setting globals.


reset_postdata()

public function reset_postdata(): void

Restores $post global to current query’s post.


Conditional Methods

All return bool. Some accept optional parameters for specific checks.

Method Parameters
is_archive()
is_post_type_archive() $post_types = ''
is_attachment() $attachment = ''
is_author() $author = ''
is_category() $category = ''
is_tag() $tag = ''
is_tax() $taxonomy = '', $term = ''
is_date()
is_day()
is_month()
is_year()
is_time()
is_feed() $feeds = ''
is_comment_feed()
is_front_page()
is_home()
is_privacy_policy()
is_page() $page = ''
is_paged()
is_preview()
is_robots()
is_favicon()
is_search()
is_single() $post = ''
is_singular() $post_types = ''
is_trackback()
is_404()
is_embed()
is_main_query()

Internal Methods

init()

public function init(): void

Resets all properties to defaults.


fill_query_vars()

public function fill_query_vars( array $query_vars ): array

Fills in missing query variables with defaults.


parse_tax_query()

public function parse_tax_query( array &$query_vars ): void

Parses taxonomy-related query vars.


set_404()

public function set_404(): void

Sets 404 state. Fires set_404 action.


Example Queries

Recent Posts with Thumbnails

$query = new WP_Query( array(
    'post_type'      => 'post',
    'posts_per_page' => 5,
    'meta_query'     => array(
        array(
            'key'     => '_thumbnail_id',
            'compare' => 'EXISTS',
        ),
    ),
) );

Products by Price Range

$query = new WP_Query( array(
    'post_type'  => 'product',
    'meta_query' => array(
        array(
            'key'     => '_price',
            'value'   => array( 10, 50 ),
            'type'    => 'NUMERIC',
            'compare' => 'BETWEEN',
        ),
    ),
    'orderby'    => 'meta_value_num',
    'meta_key'   => '_price',
    'order'      => 'ASC',
) );

Posts in Multiple Taxonomies

$query = new WP_Query( array(
    'post_type' => 'post',
    'tax_query' => array(
        'relation' => 'AND',
        array(
            'taxonomy' => 'category',
            'field'    => 'slug',
            'terms'    => 'news',
        ),
        array(
            'taxonomy' => 'post_tag',
            'field'    => 'slug',
            'terms'    => array( 'featured', 'breaking' ),
            'operator' => 'IN',
        ),
    ),
) );

Complex Date Query

$query = new WP_Query( array(
    'post_type'  => 'event',
    'date_query' => array(
        array(
            'after'  => array(
                'year'  => 2023,
                'month' => 6,
            ),
            'before' => array(
                'year'  => 2023,
                'month' => 12,
                'day'   => 31,
            ),
            'inclusive' => true,
        ),
        array(
            'hour'    => 9,
            'compare' => '>=',
        ),
        array(
            'hour'    => 17,
            'compare' => '<=',
        ),
        'relation' => 'AND',
    ),
) );

Optimized ID-Only Query

$post_ids = new WP_Query( array(
    'post_type'              => 'post',
    'posts_per_page'         => 100,
    'fields'                 => 'ids',
    'no_found_rows'          => true,
    'update_post_meta_cache' => false,
    'update_post_term_cache' => false,
) );

// $post_ids->posts is array of integers