WP_Query arguments: status, order and pagination. Create an instance of the class and queries for messages. #2 Display one random post

If you've been following our series of articles, you probably already know how the WP_Query class works and how you can use it to create your own queries. To determine what data you want to extract from the database, you need to become familiar with the arguments of this class and learn how to use them correctly.

Today we will get acquainted with the arguments for custom fields ( custom fields), but first let's remember how to use arguments in WP_Query.

Let's remember how arguments work in WP_Query

When you use WP_Query in themes or plugins, there are four main elements you need to include in your code:

  • Arguments for a request that use parameters;
  • The request itself;
  • Cycle;
  • The final stage: resetting the recording data.

In practice it looks like this:

have_posts()) ( // start of the data processing cycle from the query results while ($query->have_posts()) ( $query->the_post(); // contents of the queried post) ) // restoring the original post data wp_reset_postdata(); ?>

The arguments tell WordPress what data to retrieve from the database:

$args = array(// Arguments for your request);

As you can see, the arguments are enclosed in an array.

Creating Code for the Arguments

Exists special way setting arguments in an array:

$args = array("parameter1" => "value", "parameter2" => "value", "parameter3" => "value");

It is necessary to enclose the parameters and their values ​​in single quotes, and also use => between them. Each argument is separated by a comma. If you do something wrong here, then WordPress may not poll all the arguments you specify, and nothing will be displayed on the screen.

Custom Field Options

Custom fields ( also known as post metadata) can use a separate WP_Meta_Query class. Therefore, to obtain post metadata, you can use either WP_Meta_Query or WP_Query ( which still accesses WP_Meta_Query). But if you need to query metadata and other elements ( like post type), then only WP_Query should be used.

The main difference in using this class and WP_Query is that WP_Query allows you to create simple arguments without having to use nested arrays.

Options for a simple custom field request

Basic WP_Query parameters for running queries on custom fields:

  • meta_key( string): custom field key;
  • meta_value( string
  • meta_value_num( number): custom field value;
  • meta_compare( string): operator for testing " meta_value". Valid values: "=", "!=", ">", ">=", "<", "<=", "LIKE", "NOT LIKE", "IN", "NOT IN", "BETWEEN", "NOT BETWEEN", "NOT EXISTS", "REGEXP", "NOT REGEXP" или "RLIKE". Значение по умолчанию: "=".

Use these options to create simple queries against custom fields. For example, to display records that contain custom fields with the key key1 ( regardless of its meaning), you need to use the following argument:

$args = array("meta_key" => "key1");

This argument will get all records with a custom field with key1 , regardless of the value. To assign a specific value, you need to add an additional argument:

$args = array("meta_key" => "key1", "meta_value" => "value1");

This argument will display all records with a custom field that has a key1 with a value of value1 .

You can also retrieve all records with a custom field whose value will be value1 , regardless of the key. This is necessary when multiple custom field keys with duplicate values ​​are used:

$args = array("meta_value" => "value1");

As you can see, you can direct a query to an arbitrary field by key or by value, and it is not at all necessary to specify both arguments each time.

We use the meta_compare argument

You may have noticed that there are many options for the meta_compare argument. Let's look at the ones that are used most often:

  • =: Equal. This is the default setting. That is, if you don't use the meta_compare argument, WP_Query will use it;
  • !+: Not equal;
  • >: More than;
  • >=: Greater than or equal to;
  • LIKE: This option ignores the case in which you enter the value. Here you can even use special characters to search for values;
  • NOT LIKE: Works on the same principle as LIKE, but is completely opposite;
  • IN: Use this option with an array as the 'value' argument to search for entries with one or more values ​​in the array;
  • BETWEEN: Used with an array of two numeric values ​​(specified in the meta_value argument) to find records with a custom field value that is between (but not equal to) those two values;
  • NOT BETWEEN: Queries for records with a custom field value that is outside the specified range of two numeric values ​​in meta_value.

Using the meta_compare argument, you can exclude the keys or values ​​of a custom field. To retrieve all records except those whose key value uses key1 , you would use the following code:

$args = array("meta_key" => "key1", "meta_compare" => "!=");

You can use the value 'NOT IN' in the meta_compare argument, which can also be used with a string of multiple values:

$args = array("meta_key" => "key1, key2", "meta_compare" => "NOT IN");

This code queries records that do not have custom fields with key1 or key2 values. If you need to query for records with a specific custom field but not another, you can use a nested array, which I'll tell you about later.

The examples above use non-numeric values. You can use WP_Query with custom fields that have numeric values, not only to retrieve posts with those values, but also to query posts that have a custom field value higher or lower than those values. For example, this can be useful in an online store when you need to search for products cheaper or more expensive than the specified cost.

To find records with a custom field value greater than a given number, you need to use the following code:

$args = array("meta_key" => "numkey", "meta_value" => "100", "meta_compare" => ">");

This query will return all records whose custom field value is greater than 100. If you need to request records with values ​​from 100 and above, you can use the "meta_compare" => ">=" parameter.

You can also use the BETWEEN argument and an array to find records whose custom fields use values ​​in a specific range:

$args = array("meta_key" => "numkey", "meta_value" => array("100", "200"), "meta_compare" => "BETWEEN");

Such a query will allow you to find all records with custom field values ​​between 100 and 200.

Queries for nested custom fields

If you need to run a query on several custom fields or use more than one operator, you can use a nested array.

The request structure will be as follows:

$args = array("meta_query" => array("relation" => "", // Optional argument. array(// `meta_query` arguments will be here.)));

The structure of the "meta_query" argument in the WP_Query class will be the same as when using the WP_Meta_Query class, which we will talk about in detail in the following articles.

With the release of WordPress version 4.1, it became possible to use multiple levels of nested arrays to create even more complex and precise queries. The structure of such requests looks something like this:

$args = array("meta_query" => array("relation" => "", // Optional argument. array("relation" => "", array (// First set of `meta_query` arguments.), array ( // Second set of `meta_query` arguments.))));

This approach allows you to use different relationships at different levels in a query. For example, you can create a query for records with one value in one custom field, and both values ​​in another custom field.

In conclusion

Using the WP_Query class to create post metadata queries ( or custom fields) provides the flexibility to work with many different arguments in combination with operators.

If you only want to use post metadata arguments in your query ( and do not combine them with others), then you can also use the WP_Meta_Query class, which we'll talk about later.

Translation of the article “ WP_Query Arguments: Custom Fields” was prepared by the friendly team of the Website Building from A to Z project.

Prestashop is an online store management engine. On the Internet you can find many paid and free Prestashop modules that help improve product pages and increase the number of conversions. In this article, we will look at the 5 best SEO modules.

In today's article in our series exploring the WP_Query class, you'll learn about several arguments that you can use with WP_Query to query:

  • status;
  • order;
  • pagination.

These arguments can be used to retrieve records from the database, in attachment queries, to reorder and sort records, specify how many records to display, and much more.

Let's remember how arguments work in WP_Query

When you use WP_Query in your own themes or plugins, there are four main elements you need to include in your code:

  • Arguments for a request that use parameters;
  • The request itself;
  • Cycle;
  • The final stage: resetting the recording data.

In practice it looks like this:

have_posts()) ( // start of the data processing cycle from the query results while ($query->have_posts()) ( $query->the_post(); // contents of the queried post) ) // restoring the original post data wp_reset_postdata(); ?>

Arguments tell WordPress what data to retrieve from the database. Let's focus on the very beginning of the code:

$args = array(// Arguments for your request);

As you can see, the arguments are enclosed in an array.

Creating Code for the Arguments

There is a specific syntax for initializing arguments in an array:

$args = array("parameter1" => "value", "parameter2" => "value", "parameter3" => "value");

You should enclose parameters and their values ​​in single quotes, and use => between them. Arguments are separated by commas. If you do not follow the established syntax, then WordPress may not poll all the arguments you specify, and as a result, nothing will be displayed on the screen.

Status options

As you know, WordPress gives each post a separate status. You can use the post_status parameter to query posts with one or more statuses.

The following arguments are available:

  • publish : published post or page;
  • pending : entry is pending review;
  • draft : entry in draft status;
  • auto-draft : newly created post, without any content;
  • future : scheduled entry;
  • private: the entry is not visible to visitors who are not logged in to the site;
  • inherit : modified post version or status for attached posts;
  • trash : the entry is in the trash;
  • any : requests any status except those with the parameter 'exclude_from_search' set to true (for example, auto-draft t or trash).

If you don't specify a status in your request arguments, WordPress will default to publish ; if the user is authorized on the site, then the request will also take into account records with the private status. If you run the request as an administrator, then WordPress will also take into account the protected statuses: future , draft and pending .

Let's assume that you have a poster site that uses own type event records, and the date on which the event is scheduled is used as the publication date. By default, WordPress will not display events that have not yet taken place. Despite what you have planned, the publication date is in the future, which means the post status will be future .

To work around this issue, you can use the following arguments:

$args = array("post_type" => "event", "post_status" => "future");

This code will allow you to display those events that have not yet taken place, since the publish status is used for published entries. But if you need to show events that have taken place, then you need to use an array that contains more than one status:

$args = array("post_type" => "event", "post_status" => array("future", "publish"));

The post_status parameter is important when querying attachments because the status is inherit rather than publish. To query for all attachments, you can use the following code:

$args = array("post_type" => "attachment", "post_status" => "inherit");

But you can replace inherit with any other status that will produce a similar result.

Sort Options

There are two parameters that can be used to sort records obtained using WP_Query: order and orderby. As you already understood, order determines the order in which the records are displayed in the loop, and orderby determines which field in the database they will be sorted by.

order parameter

There are only arguments that you can use for sorting:

ASC: Ascending (1, 2, 3; a, b, c).
DESC: descending (3, 2, 1; c, b, a).

If you don't include an argument for order, WordPress will default to DESC .

orderby parameter

You can sort records by several fields:

  • none : no sorting conditions ( available from version 2.8);
  • ID : sort by post id. Don't forget about upper case;
  • author : sort by author;
  • title : sort by title;
  • name : sort by slug entry;
  • type : sort by post type;
  • date : sort by date;
  • modified : sort by last modified date;
  • parent : sort by id of the parent post/page;
  • rand: random order;
  • comment_count : sort by number of comments;
  • menu_order : sort by page order. Most commonly used for pages ( here the value that is specified in the meta block when editing the page is used), as well as for attachments ( uses the integer from the Insert/Load Media dialog box). Can also be used for any post type with menu_order enabled;
  • meta_value : sort by meta key value or custom one;
  • fields: Will only work if the meta_key parameter is set. Meta values ​​are sorted alphabetically rather than numerically ( that is, 34 will be printed before the number 4);
  • meta_value_num : Sort by numeric meta value. As with meta_value , the meta_key argument must be used in the request;
  • post__in : saves the sorting by post IDs set in the post__in array.

By default, the date field is used for sorting. That is, it is sorted by publication date.

If you want to sort records by title in descending order, you can use the following arguments:

$args = array("orderby" => "title", "order" => "ASC");

Sorting by multiple fields

To sort records by multiple fields, you need to use an array with the orderby parameter, and with the order parameter if you want each field to be sorted in a different order.

Let's say you have a custom field called ratings that you want to use for sorting in an online store. You can sort by ascending rating and then by title using the following code:

$args = array("orderby" => array("meta_value_num", "title"), "order" => "ASC", "meta_key" => "rating");

I've included a meta_key argument in the request and this will let WordPress know what custom field we're using. This is necessary precisely because WordPress stores post metadata in the wp_postmeta table, and not in wp_posts.

But what if you want to sort by rating in descending order and then by title in ascending order? In this case, you should use a different array:

$args = array("orderby" => array("meta_value_num", "title"), "order" => array("DESC", "ASC"), "meta_key" => "rating");

You can also sort by multiple fields if you don't want to use post metadata. For example, to sort posts by type and then by date, you could use the following code:

$args = array("orderby" => array("type", "date"), "order" => array("ASC", "DESC"));

This code will sort by post type in ascending order, and then, within each post type, by date in descending order.

Pagination options

We move on to another set of parameters, which is associated with page-by-page display of content, with pagination. These parameters help determine how many records will be queried and how pagination will occur.

The following options are available:

  • nopaging ( boolean): Display all posts or use pagination. The default value is 'false', that is, page output is used;
  • posts_per_page ( int): number of records per page;
  • posts_per_archive_page (int): number of records per page, but only on the archive page;
  • offset ( int): number of records after which output begins;
  • paged( int): page in the archive from which pages are derived;
  • page ( int): Number of pages for the static home page. Displaying records that should be in normal mode only appear on page X when the static home page is enabled ( Front Page);
  • ignore_sticky_posts (boolean): ignore attached posts. The default value is false .

Number of entries and skipping entries

To show the five most latest entries, use the following code:

$args = array("posts_per_page" => "5");

Showing the five most recent entries, excluding the most recently published one:

$args = array("posts_per_page" => "5", "offset" => "1");

Please note that although you are retrieving records from six latest entries in the database, you are still using 'posts_per_page' => '5', since this is the number of records that should be displayed.

You can create two queries: one to display the most recent entries, and a second to display 10 more entries, excluding that entry:

To display all posts you can use posts_per_page :

$args = array("posts_per_page" => "-1");

Attached posts

Typically, pinned posts appear first in any query. If you need to override this setting, use the ignore_sticky_posts parameter:

$args = array("posts_per_page" => "5", "ignore_sticky_posts" => true);

The above arguments will retrieve the last five entries, whether they are attached or not.

If you want to display only attached posts, you need to use the get_option() function and the post__in argument as follows:

$sticky = get_option("sticky_posts"); $args = array("posts_per_page" => "5", "post__in" => $sticky);

The above code will retrieve the last five attached posts. If there are fewer than five (for example, three), then only the available number of attached records will be displayed.

Pagination in archives

You can also use pagination options to determine how retrieved entries will be distributed across multiple archive pages or search pages.

For example, the following code could be used on an archive page to display 20 entries per page:

$args = array("posts_per_archive_page" => "20");

Note: the posts_per_archive_page argument overrides posts_per_page .

init() Initialise the object, set all properties to null, zero or false. parse_query($query) Takes a query string defining the request, parses it and populates all properties apart from $posts , $post_count , $post and $current_post . parse_query_vars() Reparse the old query string. get($query_var) Get a named query variable. set($query_var, $value) Set a named query variable to a specific value. &get_posts() Fetch and return the requested posts from the database. Also populate $posts and $post_count . Note: This is called during construction if WP_Query is constructed with arguments. It is not

idempotent and should not be called more than once on the same query object. Doing so may result in a broken query.

next_post() (to be used when in ) Advance onto the next post in $posts . Increment $current_post and set $post to the (new) current post object (note: this does not set the global $post variable, only the WP_Query object"s instance variable.) Returns the current post object

(This is deprecated pleases use "next_post_link()")

  • the_post() (to be used when in ) Advance onto the next post, and set the global $post variable. (have_posts() (to be used when in , or just before The Loop) Determine if we have posts remaining to be displayed. Calls rewind_posts() and returns false if don"t have posts remaining. Because of the rewind, you can
  • "t rely on have_posts() staying false. See . rewind_posts() Reset $current_post and $post . &query($query) Call parse_query() and get_posts() . Return the results of get_posts() . get_queried_object() Set $queried_object if it"s not already set and return it. (string get_queried_object_id() Set $queried_object_id if it"s not already set and return it. WP_Query($query = "") (constructor) If you provide a query string, call query() with it.
  • Parameters (Author Parameters
  • Show posts associated with certain author. (Author Parameters author

int | string

) - use author id or comma-separated list of IDs.

author_name

) - use " user_nicename " - NOT name.

author__in

array

author__not_in

) - use author id (available since ).

Show Posts for one Author

Display posts by author, using author id: $query = new WP_Query(array("author" => 123)); those from an author(singular) by prefixing its id with a "-" (minus) sign:

$query = new WP_Query(array("author" => -12));

Multiple Author Handling

Display posts from multiple authors:

$query = new WP_Query(array("author__in" => array(2, 6)));

You can also exclude multiple author this way:

$query = new WP_Query(array("author__not_in" => array(2, 6)));

Category Parameters

Show posts associated with certain categories.

  • cat (int) - use category id.
  • category_name (string) - use category slug.
  • category__and (Author Parameters) - use category id.
  • category__in (Author Parameters) - use category id.
  • category__not_in (Author Parameters) - use category id.

Show Posts for One Category

Display posts that have this category (and any children of that category), using category id:

$query = new WP_Query(array("cat" => 4));

Display posts that have this category (and any children of that category), using category slug:

$query = new WP_Query(array("category_name" => "staff"));

Display posts that have this category (not children of that category), using category id:

$query = new WP_Query(array("category__in" => 4));

Show Posts From Several Categories

Display posts that have these categories, using category id:

$query = new WP_Query(array("cat" => "2,6,17,38"));

Display posts that have these categories, using category slug:

$query = new WP_Query(array("category_name" => "staff,news"));

Display posts that have "all" of these categories:

$query = new WP_Query(array("category_name" => "staff+news"));

Exclude Posts Belonging to Category

Display posts by author, using author id: $query = new WP_Query(array("author" => 123)); those from a category by prefixing its id with a "-" (minus) sign.

$query = new WP_Query(array("cat" => "-12,-34,-56"));

Multiple Category Handling

Display posts that are in multiple categories. This shows posts that are in both categories 2 and 6:

$query = new WP_Query(array("category__and" => array(2, 6)));

To display posts from either category 2 OR 6, you could use cat as mentioned above, or by using category__in (note this does not show posts from any children of these categories):

$query = new WP_Query(array("category__in" => array(2, 6)));

You can also exclude multiple categories this way:

$query = new WP_Query(array("category__not_in" => array(2, 6)));

Tag Parameters

Show posts associated with certain tags.

  • tag (string) - use tag slug.
  • tag_id (int) - use tag id.
  • tag__and (Author Parameters) - use tag ids.
  • tag_in (Author Parameters) - use tag ids.
  • tag__not_in (Author Parameters) - use tag ids.
  • tag_slug__and (Author Parameters) - use tag slugs.
  • tag_slug__in (Author Parameters) - use tag slugs.

Show Posts for One Tag

Display posts that have this tag, using tag slug:

$query = new WP_Query(array("tag" => "cooking"));

Display posts that have this tag, using tag id:

$query = new WP_Query(array("tag_id" => 13));

Show Posts From Several Tags

Display posts that have "either" of these tags:

$query = new WP_Query(array("tag" => "bread,baking"));

parse_query($query) Takes a query string defining the request, parses it and populates all properties apart from $posts , $post_count , $post and $current_post . If WP_Query determines that the result will be singular ( is true), it will ignore the tax_query parameter. To modify tax_query , use the filter to add the required SQL statements.

Important Note: tax_query takes an Author Parameters of tax query arguments arrays(it takes an array of arrays). This construct allows you to query multiple taxonomies by using the relation parameter in the first (outer) array to describe the boolean relationship between the taxonomy arrays.

Simple Taxonomy Query:

Display posts tagged with bob, under people custom taxonomy:

$args = array("post_type" => "post", "tax_query" => array(array("taxonomy" => "people", "field" => "slug", "terms" => "bob", ),),); $query = new WP_Query($args);

Multiple Taxonomy Handling:

Display posts from several custom taxonomies:

$args = array("post_type" => "post", "tax_query" => array("relation" => "AND", array("taxonomy" => "movie_genre", "field" => "slug", "terms" => array("action", "comedy"),), array("taxonomy" => "actor", "field" => "term_id", "terms" => array(103, 115, 206 ), "operator" => "NOT IN",),),); $query = new WP_Query($args);

Display posts that are in the quotes category OR have the quote :

$args = array("post_type" => "post", "tax_query" => array("relation" => "OR", array("taxonomy" => "category", "field" => "slug", "terms" => array("quotes"),), array("taxonomy" => "post_format", "field" => "slug", "terms" => array("post-format-quote"), ),),); $query = new WP_Query($args);

Nested Taxonomy Handling:

The "tax_query" clauses can be nested, to create more complex queries. Example: Display posts that are in the quotes category OR both have the quote post format AND are in the wisdom category:

$args = array("post_type" => "post", "tax_query" => array("relation" => "OR", array("taxonomy" => "category", "field" => "slug", "terms" => array("quotes"),), array("relation" => "AND", array("taxonomy" => "post_format", "field" => "slug", "terms" => array("post-format-quote"),), array("taxonomy" => "category", "field" => "slug", "terms" => array("wisdom"),),),) ,); $query = new WP_Query($args);

Search Parameter

Show posts based on a keyword search.

  • s (string) - Search keyword.

Show Posts based on a keyword search

Display posts that match the search term "keyword":

$query = new WP_Query(array("s" => "keyword"));

Prepending a term with a hyphen will exclude posts matching that term. Eg, "pillow -sofa" will return posts containing "pillow" but not "sofa" (available since ).

Post & Page Parameters

Display content based on post and page parameters. Remember that default post_type is only set to display posts but not pages.

  • p (int) - use post id. Default post type is post.
  • name (string) - use post slug.
  • title (string) - use post title (available with ).
  • page_id (int) - use page id.
  • pagename (string) - use page slug.
  • post_parent (int) - use page id to return only child pages. Set to 0 to return only top-level entries.
  • post_parent__in (Author Parameters) - use post ids. Specify posts whose parent is in an array. (available since)
  • post_parent__not_in (Author Parameters) - use post ids. Specify posts whose parent is not in an array. Like post__in/post__not_in, id"s that are present in post_parent__in will over-ride ids specified in post_parent__not_in (available since)
  • post_in (Author Parameters) - use post ids. Specify posts to retrieve. ATTENTION If you use sticky posts, they will be included (prepended!) in the posts you retrieve whether you want it or not. To suppress this behavior use.
  • post__not_in (Author Parameters) - use post ids. Specify post NOT to retrieve. If this is used in the same query as post__in, it will be ignored.
  • post_name__in (Author Parameters) - use post slugs. Specify posts to retrieve. (available since)
  • post_type (string / Author Parameters) - use post types. Retrieves posts by , default value is " post ". If "tax_query" is set for a query, the default value becomes "any";
    • "post" - a post.
    • "page" - a page.
    • "revision" - a revision.
    • "attachment" - an attachment. While the default WP_Query post_status is "publish", attachments have a default post_status of "inherit". This means no attachments will be returned unless you also explicitly set post_status to "inherit" or "any". (See, below)
    • " nav_menu_item " - a navigation menu item
    • " any " - retrieves any type except revisions and types with "exclude_from_search" set to true.
    • Custom Post Types (e.g. movies)

Show Post by Type

Display only pages:

$query = new WP_Query(array("post_type" => "page"));

Display " any " post type (retrieves any type except revisions and types with "exclude_from_search" set to TRUE):

$query = new WP_Query(array("post_type" => "any"));

Display multiple post types, including custom post types:

$args = array("post_type" => array("post", "page", "movie", "book")); $query = new WP_Query($args);

Status Parameters

  • post_status (string / Author Parameters) - use post status. Retrieves posts by . Default value is "publish", but if the user is logged in, "private" is added. Public are also included by default. And if the query is run in an admin context (administration area or AJAX call), protected statuses are added too. By default protected statuses are "future", "draft" and "pending".
    • " publish " - a published post or page.
    • "pending" - post is pending review.
    • "draft" - a post in draft status.
    • "auto-draft" - a newly created post, with no content.
    • "future" - a post to publish in the future.
    • "private" - not visible to users who are not logged in.
    • "inherit" - a revision. see.
    • "trash" - post is in trashbin (available since ).
    • " any " - retrieves any status except those from post statuses with "exclude_from_search" set to true (i.e. trash and auto-draft).

Show Post by Status

Display only drafts:

$query = new WP_Query(array("post_status" => "draft"));

Display multiple post status:

$args = array("post_status" => array("pending", "draft", "future")); $query = new WP_Query($args);

Display all attachments:

$args = array("post_status" => "any", "post_type" => "attachment"); $query = new WP_Query($args);

Comment Parameters

$paged = (get_query_var("page")) ? get_query_var("page") : 1; $query = new WP_Query(array("paged" => $paged));

Show Sticky Posts

Display just the first sticky post:

$sticky = get_option("sticky_posts"); $query = new WP_Query(array("p" => $sticky));

Display just the first sticky post, if none return the last post published:

$sticky = get_option("sticky_posts"); $args = array("posts_per_page" => 1, "post__in" => $sticky, "ignore_sticky_posts" =>

Display just the first sticky post, add this line to above block:

If ($sticky) ( // insert here your stuff... )

Don't Show Sticky Posts

Exclude all sticky posts from the query:

$query = new WP_Query(array("post__not_in" => get_option("sticky_posts")));

Return ALL posts within the category, but don"t show ("ignore") sticky posts at the top (They will still show in their natural position, e.g. by date):

$query = new WP_Query(array("ignore_sticky_posts" => 1, "posts_per_page" => 3, "cat" => 6);

Exclude sticky posts from a category. Return posts within the category, but exclude sticky posts completely, and adhere to paging rules:

$paged = get_query_var("paged") ? get_query_var("paged") : 1; $sticky = get_option("sticky_posts"); $args = array("cat" => 3, "ignore_sticky_posts" => 1, "post__not_in" => $sticky, "paged" => $paged,); $query = new WP_Query($args);

Order & Orderby Parameters

Sort retrieved posts.

  • order (string | array) - Designates the ascending or descending order of the "orderby" parameter. Defaults to "DESC". An array can be used for multiple order/orderby sets.
    • "ASC" - ascending order from lowest to highest values ​​(1, 2, 3; a, b, c).
    • " DESC " - descending order from highest to lowest values ​​(3, 2, 1; c, b, a).
  • orderby (string | array) - Sort retrieved posts by parameter. Defaults to "date (post_date)". One or more options can be passed.
    • " none " - No order (available since ).
    • "ID" - Order by post id. Note the capitalization.
    • "author" - Order by author. ("post_author" is also accepted.)
    • " title " - Order by title. (" post_title "is also accepted.)
    • " name " - Order by post name (post slug). (" post_name " is also accepted.)!}
    • " type " - Order by (available since ). ("post_type" is also accepted.)
    • " date " - Order by date. ("post_date" is also accepted.)
    • "modified" - Order by last modified date. ("post_modified" is also accepted.)
    • " parent " - Order by post/page parent id. ("post_parent" is also accepted.)
    • " rand " - Random order. You can also use " RAND(x) " where " x " is an integer seed value. Note an "order" parameter needs to be present for "orderby" rand to work.
    • " comment_count " - Order by number of comments (available since ).
    • " relevance " - Order by search terms in the following order: First, whether the entire sentence is matched. Second, if all the search terms are within the titles. Third, if any of the search terms appear in the titles. And, fourth, if the full sentence appears in the contents.
    • "menu_order" - Order by Page Order. Used most often for ( Order field in the Edit Page Attributes box) and for (the integer fields in the Insert / Upload Media Gallery dialog), but could be used for any post type with distinct " menu_order " values ​​(they all default to 0).
    • " meta_value " - Note that a" meta_key=keyname " must also be present in the query. Note also that the sorting will be alphabetical which is fine for strings (i.e. words), but can be unexpected for numbers (e.g. 1, 3, 34, 4, 56, 6, etc, rather than 1, 3, 4, 6, 34, 56 as you might naturally expect). Use " meta_value_num " instead for numeric values. You may also specify " meta_type " if you want to cast the meta value as a specific type. Possible values are "NUMERIC", "BINARY", "CHAR", "DATE", "DATETIME", "DECIMAL", "SIGNED", "TIME", "UNSIGNED", same as in " $meta_query ". When using " meta_type " you can also use " meta_value_* " accordingly. For example, when using DATETIME as " meta_type " you can use " meta_value_datetime " to define order structure.!}
    • " meta_value_num " - Order by numeric meta value (available since ). Also note that a " meta_key=keyname " must also be present in the query. This value allows for numerical sorting as noted above in " meta_value ".
    • " post__in " - Preserve post ID order given in the " post__in " array (available since ). !} Note
    • " post_name__in " - Preserve post slug order given in the " post_name__in " array (available since ). Note- the value of the order parameter does not change the resulting sort order.
    • " post_parent__in " - Preserve post parent order given in the " post_parent__in " array (available since ). Note- the value of the order parameter does not change the resulting sort order.

Show Posts sorted by Title, Descending order

Display posts sorted by post "title" in a descending order:

$args = array("orderby" => "title", "order" =>

Display posts sorted by "menu_order" with a fallback to post "title", in a descending order:

$args = array("orderby" => "menu_order title", "order" => "DESC",); $query = new WP_Query($args);

Show Random Post

Display one random post:

$args = array("orderby" => "rand", "posts_per_page" => 1,); $query = new WP_Query($args);

Show Popular Posts

Display posts ordered by comment count:

$args = array("orderby" => "comment_count"); $query = new WP_Query($args);

Show Products sorted by Price

Display posts with "Product" type ordered by "Price" custom field:

$args = array("post_type" => "product", "orderby" => "meta_value_num", "meta_key" => "price",); $query = new WP_Query($args);

Multiple "orderby" values

Display pages ordered by "title" and "menu_order". (title is dominant):

$args = array("post_type" => "page", "orderby" => "title menu_order", "order" => "ASC",); $query = new WP_Query($args);

Multiple "orderby" values ​​using an array

Display pages ordered by "title" and "menu_order" with different sort orders (ASC/DESC) (available since ):

$args = array("orderby" => array("title" => "DESC", "menu_order" => "ASC")); $query = new WP_Query($args);

Multiple orderby/order pairs

$args = array("orderby" => array("meta_value_num" => "DESC", "title" => "ASC"), "meta_key" => "age"); $query = new WP_Query($args);

"orderby" with "meta_value" and custom post type

Display posts of type "my_custom_post_type", ordered by "age", and filtered to show only ages 3 and 4 (using meta_query).

$args = array("post_type" => "my_custom_post_type", "meta_key" => "age", "orderby" => "meta_value_num", "order" => "ASC", "meta_query" => array(array( "key" => "age", "value" => array(3, 4), "compare" => "IN",),),); $query = new WP_Query($args);

"orderby" with multiple "meta_key"s

If you wish to order by two different pieces of postmeta (for example, City first and State second), you need to combine and link your meta query to your orderby array using "named meta queries". See the example below:

$q = new WP_Query(array("meta_query" => array("relation" => "AND", "state_clause" => array("key" => "state", "value" => "Wisconsin",) , "city_clause" => array("key" => "city", "compare" => "EXISTS",),, "orderby" => array("city_clause" => "ASC", "state_clause" = > "DESC",),));

Date Parameters

Show posts associated with a certain time and date period.

  • year (int) - 4 digit year (e.g. 2011).
  • monthnum (int
  • w (int) - Week of the year (from 0 to 53). Uses MySQL WEEK command. The mode is dependent on the "start_of_week" option.
  • day (int
  • hour (int) - Hour (from 0 to 23).
  • minute (int) - Minute (from 0 to 60).
  • second (int) - Second (0 to 60).
  • m (int) - YearMonth (For e.g.: 201307 ).
  • date_query (Author Parameters) - Date parameters (available since ).
    • year (int) - 4 digit year (e.g. 2011).
    • month (int) - Month number (from 1 to 12).
    • week (int) - Week of the year (from 0 to 53).
    • day (int) - Day of the month (from 1 to 31).
    • hour (int) - Hour (from 0 to 23).
    • minute (int) - Minute (from 0 to 59).
    • second (int) - Second (0 to 59).
    • after (string/array) - Date to retrieve posts after. Accepts strtotime()
      • year (string
      • month (string) The month of the year. Accepts numbers 1-12. Default: 12.
      • day (string) The day of the month. Accepts numbers 1-31. Default: last day of month.
    • before (string/array) - Date to retrieve posts before. Accepts strtotime() -compatible string, or array of "year", "month", "day" values:
      • year (string) Accepts any four-digit year. Default is empty.
      • month (string) The month of the year. Accepts numbers 1-12. Default: 1.
      • day (string) The day of the month. Accepts numbers 1-31. Default: 1.
    • inclusive (boolean) - For after/before, whether exact value should be matched or not".
    • compare (string) - See WP_Date_Query::get_compare().
    • column (string) - to query against. Default: "post_date".
    • relation (string) - OR or AND, how the sub-arrays should be compared. Default:AND.

Returns posts dated December 12, 2012:

$query = new WP_Query("year=2012&monthnum=12&day=12");

$args = array("date_query" => array(array("year" => 2012, "month" => 12, "day" => 12,),),); $query = new WP_Query($args);

Returns posts for today:

$today = getdate(); $query = new WP_Query("year=" . $today["year"] . "&monthnum=" . $today["mon"] . "&day=" . $today["mday"]);

$today = getdate(); $args = array("date_query" => array(array("year" => $today["year"], "month" => $today["mon"], "day" => $today["mday "],),),); $query = new WP_Query($args);

Returns posts for this week:

$week = date("W"); $year = date("Y"); $query = new WP_Query("year=" . $year . "&w=" . $week);

$args = array("date_query" => array(array("year" => date("Y"), "week" => date("W"),),),); $query = new WP_Query($args);

Return posts between 9AM to 5PM on weekdays

$args = array("date_query" => array(array("hour" => 9, "compare" => ">=",), array("hour" => 17, "compare" => "<=",), array("dayofweek" =>array(2, 6), "compare" => "BETWEEN",),), "posts_per_page" =>

Return posts from January 1st to February 28th

$args = array("date_query" => array(array("after" => "January 1st, 2013", "before" => array("year" => 2013, "month" => 2, "day" => 28,), "inclusive" => true,),), "posts_per_page" => -1,); $query = new WP_Query($args);

Note that if a strtotime() -compatible string with just a date was passed in the before parameter, this will be converted to 00:00:00 on that date. In this case, even if inclusive was set to true, the date would not be included in the query. If you want a before date to be inclusive, include the time as well, such as "before" => "2013-02-28 23:59:59" , or use the array format, which is adjusted automatically if inclusive is set .

Return posts made over a year ago but modified in the past month

$args = array("date_query" => array(array("column" => "post_date_gmt", "before" => "1 year ago",), array("column" => "post_modified_gmt", "after" => "1 month ago",),), "posts_per_page" => -1,); $query = new WP_Query($args);

The "date_query" clauses can be nested, in order to construct complex queries. See for details on the syntax.

Custom Field Parameters

Show posts associated with a certain custom field.

This part of the query is parsed by , so check as well in case this list of arguments isn't up to date.

  • meta_key (string) - Custom field key.
  • meta_value (string) - Custom field value.
  • meta_value_num (number) - Custom field value.
  • meta_compare (string) - Operator to test the " meta_value ". Possible values ​​are"=", "!=", ">", ">=", "!}<", "<=", "LIKE", "NOT LIKE", "IN", "NOT IN", "BETWEEN", "NOT BETWEEN", "NOT EXISTS", "REGEXP", "NOT REGEXP" or "RLIKE". Default value is "=".
  • meta_query (Author Parameters) - Custom field parameters (available since ).
    • relation (string) - The logical relationship between each inner meta_query array when there is more than one. Possible values ​​are "AND", "OR". Do not use with a single inner meta_query array.

meta_query also contains one or more arrays with the following keys:

  • key (string) - Custom field key.
  • value (string|Author Parameters) - Custom field value. It can be an array only when compare is "IN" , "NOT IN" , "BETWEEN" , or "NOT BETWEEN" . You don"t have to specify a value when using the "EXISTS" or "NOT EXISTS" comparisons in WordPress 3.9 and up.
    (parse_query($query) Takes a query string defining the request, parses it and populates all properties apart from $posts , $post_count , $post and $current_post . Due to bug #23268 , value is required for NOT EXISTS comparisons to work correctly prior to 3.9. You must supply some string for the value parameter. An empty string or NULL will NOT work. However, any other string will do the trick and will NOT show up in your SQL when using NOT EXISTS . Need inspiration? How about "bug #23268" .)
  • compare (string) - Operator to test. Possible values ​​are "=", "!=", ">", ">=", "<", "<=", "LIKE", "NOT LIKE", "IN", "NOT IN", "BETWEEN", "NOT BETWEEN", "EXISTS" and "NOT EXISTS". Default value is "=".
  • type (string) - Custom field type. Possible values ​​are "NUMERIC", "BINARY", "CHAR", "DATE", "DATETIME", "DECIMAL", "SIGNED", "TIME", "UNSIGNED". Default value is "CHAR". You can also specify precision and scale for the "DECIMAL" and "NUMERIC" types (for example, "DECIMAL(10,5)" or "NUMERIC(10)" are valid).

The "type" DATE works with the "compare" value BETWEEN only if the date is stored at the format YYYY-MM-DD and tested with this format.

Important Note: meta_query takes an Author Parameters of meta query arguments arrays(it takes an array of arrays) - you can see this in the examples below. This construct allows you to query multiple metadatas by using the relation parameter in the first (outer) array to describe the boolean relationship between the meta queries. Accepted arguments are "AND", "OR". The default is "AND".

Simple Custom Field Query:

Display posts where the custom field key is "color", regardless of the custom field value:

$query = new WP_Query(array("meta_key" => "color"));

Display posts where the custom field value is "blue", regardless of the custom field key:

$query = new WP_Query(array("meta_value" => "blue"));

Display where the custom field value is "blue", regardless of the custom field key:

$args = array("meta_value" => "blue", "post_type" => "page"); $query = new WP_Query($args);

Display posts where the custom field key is "color" and the custom field value is "blue":

$args = array("meta_key" => "color", "meta_value" => "blue"); $query = new WP_Query($args);

Display posts where the custom field key is "color" and the custom field value IS NOT "blue":

$args = array("meta_key" => "color", "meta_value" => "blue", "meta_compare" => "!="); $query = new WP_Query($args);

Display posts where the custom field value is a number. Displays only posts where that number is less than 10. (WP_Query uses this equation to compare: $post_meta . $args["meta_compare"] . $args["meta_value"] , where "$post_meta" is the value of the custom post meta stored in each post; the actual equation with the values ​​filled in: $post_meta< 10)

$args = array("post_type" => "post", "meta_key" => "number", "meta_value_num" => 10, "meta_compare" => "<",); $query = new WP_Query($args);

Display posts where the custom field key is a set date and the custom field value is now. Displays only posts which date has not passed.

$args = array("post_type" => "event", "meta_key" => "event_date", "meta_value" => date("Ymd"), // change to how "event date" is stored "meta_compare" = > ">",); $query = new WP_Query($args);

Display "product"(s) where the custom field key is 'price' and the custom field value that is LESS THAN OR EQUAL TO 22.
By using the 'meta_value' parameter the value 99 will be considered greater than 100 as the data are stored as 'strings', not 'numbers'. For number comparison use 'meta_value_num'.

$args = array('meta_key' => 'price', 'meta_value' => '22', 'meta_compare' => '<=', 'post_type' =>'product'); $query = new WP_Query($args);

Display posts with a custom field value of zero (0), regardless of the custom field key:

$args = array('meta_value' => '_wp_zero_value'); $query = new WP_Query($args);

Single Custom Field Handling:

Display posts from a single custom field:

$args = array('post_type' => 'product', 'meta_query' => array(array('key' => 'color', 'value' => 'blue', 'compare' => 'NOT LIKE' ,),),); $query = new WP_Query($args);

(Note that meta_query expects nested arrays, even if you only have one query.)

Selects records from the database based on specified criteria. The get_posts() and query_posts() functions and all other queries related to selecting posts from the wp_posts table work on the basis of WP_Query.

Notes on filters

You can use the following filters to embed directly into the SQL query itself.

Important: if the parameter is specified, then all these hooks will not work!

Filters triggered before setting the pagination request:
  • - changes SQL "WHERE"
  • posts_join - modifies SQL "JOIN"
Filters triggered after setting a pagination request:
  • - changes SQL "WHERE" during pagination
  • posts_groupby - changes SQL "GROUP BY"
  • posts_join_paged - modifies SQL "JOIN" during pagination
  • posts_orderby - changes SQL "ORDER BY"
  • posts_distinct - changes SQL "DISTINCTROW"
  • post_limits - changes SQL "LIMIT"
  • posts_fields - changes the resulting table fields
  • post_mime_type (string/array)

    Mime recording type. Used only for attachments - posts with the "attachment" type.

    This option will only work when the post_type = attachment and post_status = inherit option. Those. Only attachments can have a MIME type.

    We will receive only images of any type

    $query = new WP_Query(array("post_mime_type" => "image", "post_type" => "attachment", "post_status" => "inherit",));

    We will only receive gif images

    $query = new WP_Query(array("post_mime_type" => "image/gif", "post_type" => "attachment", "post_status" => "inherit",));

    We will receive all types of attachments, except images

    $query = new WP_Query(array("post_mime_type" => array("application","text","video","audio"), "post_type" => "attachment", "post_status" => "inherit", ));

    Options Statuses

    Retrieves posts with the specified status.

    Post_status (string/array)

    Post status.

    By default, publish , and if the user is authorized, private is also added. If the request is launched from the admin part, protected status types are also added: future, draft and pending. All status types:

    • publish - published post.
    • pending - post is being moderated.
    • draft - draft.
    • auto-draft - a draft saved by WordPress itself (auto-save).
    • future - planned post.
    • private - personal post.
    • inherit - revision or attachment.
    • trash - deleted post (in the trash). Since version 2.9.
    • any - all statuses, except for statuses whose parameter specifies exclude_from_search=true . See register_post_status() and get_post_stati() .

    Default: "publish"

    Posts by status

    We will receive only drafts:

    $query = new WP_Query("post_status=draft");

    Let's get posts with different statuses:

    $query = new WP_Query(array("post_status" => array("pending", "draft", "future")));

    We will receive all types of investments:

    $query = new WP_Query(array("post_status" => "any", "post_type" => "attachment"));

    Options Dates (times)

    Displays posts belonging to a specific time period.

    Year (number) 4 digits of the year (2013) monthnum (number) Month number (1 - 12) w (number) Week of the year (from 0 to 53) day (number) Day of the month (1 - 31) hour (number) Hour (0 - 23) minute (number) Minute (0 - 60) second (number) Second (0 - 60) m (number) YearMonth (201306) date_query (array)

    Parameters by which the request will be configured. It works based on a separate class: WP_Date_Query.

    This parameter is specified as an array, which can contain nested arrays. Parameters: column , compare , relation for the main array work as default parameters for nested arrays (if any).

      column - field in the database for the request. May be:
      post_date
      post_date_gmt
      post_modified
      post_modified_gmt
      comment_date
      comment_date_gmt
      user_registered
      Default: "post_date"

      compare - Comparison operator for all nested arrays by default. Maybe: Maybe: = , != , > , >= ,< , <= , IN , NOT IN , BETWEEN , NOT BETWEEN .
      Default: "="

      relation - operator if several arrays with dates are specified:
      AND (consider all specified arrays simultaneously).
      OR (if there are matches with at least one specified array).
      Default - OR

      The options below should be used in nested arrays. They define a query for a single date.

      Also all parameters below can be used in the main array.

      • before (string/array)- Date of records “until” which will be received. Takes a string that the strtotime() function will understand: all possible formats. Or you can pass an array with indexes: year , month , day: array("year"=>"2015", "month"=>"5", "day"=>"28")

        after (string/array)- The date of the records “after” which will be received. Takes a string that the strtotime() function will understand: all possible formats. Or you can pass an array with indexes: year , month , day: array("year" => "2015", "month" => "5", "day" => "28")
        Relative to the site's current time (not UTC).

        column (line)- see above, only for a specific date. Default: top array value.

        compare (line)- see above, only for a specific date. The default is "=".

        inclusive (logical)- arguments before and after are processed inclusively if true. Default: false.

      • year (number/array)- year, for example 2013
      • dayofyear (number/array)- number of the day in the year, 1-366.
      • month (number/array)- month, 1-12
      • week (number/array)- week, 0-53
      • day (number/array)- day, 1-31
      • dayofweek (number/array)- day of the week, 1-7, where 1 is Sunday
      • dayofweek_iso (number/array)- day of the week, 1-7, where 1 is Monday
      • hour (number/array)- hour, 0-23
      • minute (number/array)- minute, 0-60
      • second (number/array)- second, 0-60

      In the parameters: year , month , week , dayofyear , day , dayofweek , dayofweek_iso , hour , minute , second you can specify several values, in the form of an array, if the compare parameter matches.

    #1. Let's get today's posts:

    $today = getdate(); $query = new WP_Query("year=" . $today["year"] . "&monthnum=" . $today["mon"] . "&day=" . $today["mday"]);

    #2. Let's get posts for the last week:

    $week = date("W"); $year = date("Y"); $query = new WP_Query("year=" . $year . "&w=" . $week);

    #3. Let's get posts for December 20:

    $query = new WP_Query("monthnum=12&day=20");

    #4. Let's get posts for the period of time from March 1 to March 15, 2010:

    // Create a new function that will add a where condition to the query function filter_where($where = "") ( // from March 1 to March 15, 2010 $where .= " AND post_date >= "2010-03-01" AND post_date< "2010-03-16""; return $where; } add_filter("posts_where", "filter_where"); $query = new WP_Query($query_string); remove_filter("posts_where", "filter_where");

    The queries above return posts for a specified period in history: "Posts for X month, X day." They cannot receive posts for an arbitrary period of time in relation to the present. Therefore, queries like “Posts for the last 30 days” or “Posts for the last year” are not possible in the basic version; for such queries you need to use the “posts_where” filter. The examples below show how to do this.

    #5. Let's get posts for the last 30 days:

    // Create a new function that will add a where condition to the query function filter_where($where = "") ( // for the last 30 days $where .= " AND post_date > "" . date("Y-m-d", strtotime("-30 days ")). """; return $where; ) add_filter("posts_where", "filter_where"); $query = new WP_Query($query_string); remove_filter("posts_where", "filter_where");

    #6. We will receive posts for the period from 30 to 60 days before the present:

    // Create a new function that will add a where condition to the query function filter_where($where = "") ( // from 30 to 60 days $where .= " AND post_date >= "" . date("Y-m-d", strtotime("- 60 days")) . """ . " AND post_date<= "" . date("Y-m-d", strtotime("-30 days")) . """; return $where; } add_filter("posts_where", "filter_where"); $query = new WP_Query($query_string); remove_filter("posts_where", "filter_where");

    The "m" parameter can only be set in the list of posts in the admin panel. It is useful when you select from a select dropdown list where the date is set to YYYYmm.

    Examples with date_query parameter

    #1. We get posts between 9 and 17 o'clock:

    $args = array("date_query" => array(array("hour" => 9, "compare" => ">=",), array("hour" => 17, "compare" => "<=",), array("dayofweek" =>array(2, 6), "compare" => "BETWEEN",),), "posts_per_page" =>

    #2. We will receive posts for the period of time: January 1 to February 28:

    Dates can be specified as numbers or strings because the before and after arguments are processed by the PHP strtotime() function, which understands strings.

    $args = array("date_query" => array(array("after" => "January 1st, 2013", "before" => array("year" => 2013, "month" => 2, "day" => 28,), "inclusive" => true,),), "posts_per_page" => -1,); $query = new WP_Query($args);

    #3. Let's get posts published a year ago, but changed in the last month:

    $args = array("date_query" => array(array("column" => "post_date_gmt", "before" => "1 year ago",), array("column" => "post_modified_gmt", "after" => "1 month ago",),), "posts_per_page" => -1,); $query = new WP_Query($args);

    #4. Let's get posts for the last 2 weeks using the string "2 weeks ago":

    $query = new WP_Query(array("date_query" => array("after" => "2 weeks ago",),));

    #5. Let's get entries for the last 2 months, published on weekdays:

    $query = new WP_Query(array("date_query" => array("after" => "2 months ago", array("dayofweek" => array(1, 5), "compare" => "BETWEEN",) ,),));

    The date_query argument also works with the WP_Comment_Query class, so it can be used in the same way in the function: get_comments() .

    Options Indentation

    You can set an indent from the first post in the query results. For example, a standard request returns 6 posts, but if you add the offset=1 parameter to the same request, then 5 posts will be returned (the first post from the request will be skipped).

    Offset (number) How many posts from the query results to skip.

    Usage example

    Let's skip the first/one post (offset=1) and return the next 5:

    $query = new WP_Query("posts_per_page=5&offset=1");

    Options Sorting and ordering

    Sorts and sets the sort direction.

    Sorting options will not work if you specify the fields = ids parameter, because in this case, the request will not have fields by which you can sort the result.

    Order (line)

    The sorting direction by the orderby parameter can be:

    • ASC - in order, from smallest to largest (1, 2, 3; a, b, c).
    • DESC - in reverse order, from largest to smallest (3, 2, 1; c, b, a).
    orderby (line)

    Fields by which you can sort posts. May be

    • none - do not sort, display as is in the database. Equivalent to sorting by ID. Since version 2.8.
    • ID - sort by ID.
    • author - sorting by author IDs.
    • title - sort by title.
    • name - by the title of the post (label, post slug).
    • date - sort by publication date.
    • modified - sort by modification date.
    • type - by post type (post_type). From version 4.0
    • parent - sorting by the value of the parent field.
    • rand - random order.
    • RAND(x) - random order for numeric values. Here "x" is an integer.
    • comment_count - sorting by the number of comments. Since version 2.9.
    • relevance - by search condition (parameter s). Sorting occurs in the following order: 1) whether the entire sentence matches. 2) all search terms in the post title. 3) any words from the search query in the post title. 4) the complete sentence is found in the post content.
    • menu_order - standardly used for pages and attachments. The serial number is indicated on the post editing page.
    • meta_value - by the value of a custom field.

      Important: the meta_key parameter must also be defined. Note: the sorting will be alphabetical and will not be logical if the values ​​of arbitrary fields are numbers (for example, it will be 1, 3, 34, 4, 56, 6, etc., and not 1, 3, 4, 6, 34, 56).

    • meta_value_num - sorting by custom fields whose values ​​are numbers. Since version 2.8.
    • array key from meta_query - in this case, sorting will be by the value of a custom field specified in the meta_query array.
    • post__in - takes into account the order of the specified IDs in the post__in parameter. The order parameter is ignored.
    • post_name__in - takes into account the order of the specified names in the post_name__in parameter. The order parameter is ignored.
    • post_parent__in - takes into account the order of the specified IDs in the post_parent__in parameter. The order parameter is ignored.
    orderby = array()

    Since WordPress 4.0, you can specify an array in orderby that combines both parameters: orderby and order . This is done to sort by several columns at the same time. The syntax is as follows:

    "orderby" => array("title" => "DESC", "menu_order" => "ASC")

    #1 Sort by title

    $query = new WP_Query(array("orderby" => "title", "order" => "DESC"));

    Sort by menu order and then by title

    $query = new WP_Query(array("orderby" => "menu_order title", "order" => "DESC"));

    #2 Let’s display one random post:

    $query = new WP_Query(array("orderby" => "rand", "posts_per_page" => "1"));

    #3 Let's sort posts by the number of comments:

    $query = new WP_Query(array("orderby" => "comment_count"));

    #4 Sort products by price (custom field price):

    $query = new WP_Query(array("post_type" => "product", "orderby" => "meta_value", "meta_key" => "price"));

    #5 Multiple sorting

    Let's display posts sorted by two fields: "title" and "menu_order" (title is primary):

    $query = new WP_Query(array("post_type" => "page", "orderby" => "title menu_order", "order" => "ASC"));

    #6 Multiple sorting using an array (from version 4.0)

    Let's get pages sorted by title and menu number (menu_order) in different order (ASC/DESC):

    $query = new WP_Query(array("orderby" => array("title" => "DESC", "menu_order" => "ASC")));

    #7 Sorting by "meta_value" for a new post type (post_type)

    Let's display posts of type "my_custom_post_type" sorted by the custom field key "age" and filtered so that only posts with field values ​​3 and 4 are shown:

    $args = array("post_type" => "my_custom_post_type", "meta_key" => "age", "orderby" => "meta_value_num", "order" => "ASC", "meta_query" => array(array( "key" => "age", "value" => array(3, 4), "compare" => "IN",)));

    $query = new WP_Query($args);

    #8 Sorting by multiple metafields

    To sort the result by two different metafields, for example first by city and then by state, you need to specify the keys for the arrays in the meta_query array and then use those keys in the orderby parameter:

    Options $query = new WP_Query([ "meta_query" => [ "relation" => "AND", "state_clause" => [ "key" => "state", "value" => "Wisconsin", ], "city_clause " => [ "key" => "city", "compare" => "EXISTS", ], ], "orderby" => [ "city_clause" => "ASC", "state_clause" => "DESC", ], ]);

    Pagination (logical) nopaging (number)

    Disables pagination and displays all posts on one page.

    posts_per_page

    Number of posts on one page. If you set it to -1, then all posts will be displayed (without pagination).

    Since version 2.1, it replaces the showposts parameter. Set the paged option if pagination doesn't work after using this option. (number) Number of posts for archive pages: for pages that satisfy the is_archive() or is_search() conditions. This option overrides the "posts_per_page" and "showposts" options. (number) offset
    How many posts to skip from the top of the selection (top indent). Attention: (number) Setting this option overwrites/ignores the "paged" option and breaks pagination (solving the problem). (number) paged (logical)

    Pagination page number. Shows posts that would normally be shown on the X pagination page. Overwrites the posts_per_page page parameter

    Number for static home page. Shows posts that would normally be shown on the X pagination page of the main static page (front page).

    ignore_sticky_posts

    Ignore sticky posts or not (true/false). From version 3.1. Replaces the caller_get_posts parameter.

    Sticky posts will not appear at the top of the list, but they are not excluded and will appear in the normal order.

    #1 Posts per page

    We get 3 posts:

    $query = new WP_Query("posts_per_page=3");

    Let's get all posts:

    $query = new WP_Query("posts_per_page=-1");

    Let's get all posts and disable pagination:

    $query = new WP_Query("nopaging=true");

    #2 Top padding

    Let's get posts starting from the fourth (we'll skip the first 3):

    $query = new WP_Query("offset=3"));

    We get 5 posts that follow the first three posts:

    $query = new WP_Query(array("posts_per_page" => 5, "offset" => 3));

    #3 Posts from pagination page 6

    $query = new WP_Query("paged=6");

    #4 Posts from the current page

    Let's get posts from the current pagination page. Useful when building custom pagination:

    $query = new WP_Query([ "paged" => get_query_var("paged") ]); .

    Let's get posts from the current page and set the paged parameter to 1 when the variable is not defined on the first pagination page:

    $paged = get_query_var("paged") ? get_query_var("paged") : 1; $query = new WP_Query([ "paged" => $paged ]);

    Use get_query_var("page") if you need to get the pagination page number of the site's static front page - is_front_page() . The page variable in this case contains the pagination number on post type pages when the content uses the pagination tag

    Outputting the current pagination page on a static main page:
    $paged = get_query_var("page") ?: 1; $query = new WP_Query([ "paged" => $paged ]);
    # Only the first sticky post
    $sticky = get_option("sticky_posts"); $query = new WP_Query("p=" . $sticky);
    # First sticky post, if there is no such post, then the last one published
    $args = array("posts_per_page" => 1, "post__in" => get_option("sticky_posts"), "ignore_sticky_posts" => 1); $query = new WP_Query($args);
    # The first sticky post, if there is no such post, then we do not display anything
    $sticky = get_option("sticky_posts"); if (! empty($sticky)) ( $query = new WP_Query(array("posts_per_page" => 1, "post__in" => $sticky, "ignore_sticky_posts" => 1)); // generate the output... )
    # 5 latest sticky posts
    $sticky = get_option("sticky_posts"); // all Sticky entries rsort($sticky); // sort - new ones at the top $sticky = array_slice($sticky, 0, 5); // get the first 5 $query = new WP_Query([ "post__in"=>$sticky, "ignore_sticky_posts"=>1 ]);

    #6 Hiding sticky posts

    Let's exclude all sticky posts from the request:

    $query = new WP_Query([ "post__not_in" => get_option("sticky_posts") ]);

    Let's exclude sticky posts from the category. It will return all posts in the category, but the sticky posts will not be on top, they will be displayed as regular posts (by date):

    $query = new WP_Query([ "ignore_sticky_posts" => 1, "posts_per_page" => 3, "cat" => 6 ]);

    Let's exclude sticky posts from the category. Will return all posts in the category, but sticky posts will be completely excluded. Let’s also add a rule here for correct pagination:

    $paged = get_query_var("paged") ?: 1; $sticky = get_option("sticky_posts"); $query = new WP_Query(array("cat" => 3, "ignore_sticky_posts" => 1, "post__not_in" => $sticky, "paged" => $paged));

    Options Comments

    The post comment data is added to the WP_Query object if it is a separate post. The parameters below indicate how comments should be received in such cases.

    Comment_status (line) Comment status. (number) ping_status (number) Ping status. (number/array)

    comments_per_page

    • The number of comments to receive on an individual comment page. Default option: comments_per_page .
    • comment_count
      • The number of comments a post should have. From version 4.9. (number) If you specify a number, it will get posts with the specified number of comments (search operator =).
      • compare (line) The array allows you to specify an option for comparing the number of comments. You can specify parameters in the array:< , <= . По умолчанию: = .

    Options value

    - number of comments for comparison. (line)- how to compare the number of comments. Maybe: = , != , > , >= , (logical) true - search using the exact phrase specified in the s parameter - without adding % to the ends of the search phrase in the SQL query.
    Default: false sentence (true/false) true - search using the full search phrase, just as it is.
    false - the search phrase is divided into words and the search is performed according to the words from the search phrase.
    Default: false

    Posts found using the search phrase:

    $query = new WP_Query("s=keyword");

    Options Return fields

    Sets what data the request should return.

    Fields (string/array)

    What data to return. By default, all are returned.

    • ids - will return an array with post IDs.
    • id=>parent - will return an associative array [ parent => ID, … ].
    • Inserting any other parameters will return all fields (by default) - an array of post objects.
    no_found_rows (logical) true - do not count the number of lines found. In some cases it may speed up the request.
    Default: false

    Options Caching

    Does not add data to the cache when executing queries.

    Cache_results (true/false) Whether to cache post information.
    Default: true update_post_meta_cache (true/false) Whether to cache post meta data information.
    Default: true update_post_term_cache (true/false) Whether to cache information about linking a post to terms and taxonomies.
    Default: true lazy_load_term_meta (true/false) Whether to lazily load term metadata.
    false - will disable lazy loading of term metadata and each call to get_term_meta() will access the database.
    Default: $update_post_term_cache value

    #1 We will display 50 posts, but will not add information about posts to the cache:

    $query = new WP_Query(array("posts_per_page" => 50, "cache_results" => false));

    #2 We will display 50 posts, but will not add post meta data to the cache

    $query = new WP_Query(array("posts_per_page" => 50, "update_post_meta_cache" => false));

    #3 We will display 50 posts, but will not add information about post terms to the cache

    $query = new WP_Query(array("posts_per_page" => 50, "update_post_term_cache" => false));

    Usually you don't need to use these functions - the cache is necessary! However, this approach can be useful in a number of cases. For example, if we need to get a list of post titles and do not need any other information about the posts: neither taxonomies nor meta data. By not loading this information we can save time on unnecessary SQL queries.

    The note: If the persistent caching plugin is used, all these flags are set to false by default, since there is no need to refresh the cache every time the page is loaded.

    Options Filters (hooks)

    suppress_filters (true/false)

    Should some filters (hooks) in the WP_Query class be disabled. Enabling this parameter disables all SQL query modification filters such as posts_* or comment_feed_* .

    true - disable processing of the following hooks:

    Posts_search posts_search_orderby posts_where posts_join posts_where_paged posts_groupby posts_join_paged posts_orderby posts_distinct post_limits posts_fields posts_clauses posts_where_request posts_groupby_request posts_join_request posts_orderby_request posts_distinct_request posts_fields_request post_limits_request posts_clauses_request posts_request posts_results the_post s comment_feed_join comment_feed_where comment_feed_groupby comment_feed_orderby comment_feed_limits init() Activates an object, sets all property values ​​to null, 0 or false.

If you've been working with WordPress for a while, you should know how difficult it used to be to create lists of posts based on a large number of criteria and at the same time comply with WordPress standards. But the platform has come a long way over the past few years. And now, with the help of a powerful class WP_Query, we can create lists of messages without limiting ourselves in any way.

What is WP_Query?

Class WP_Query is one of the most important parts in the WordPress engine. Among other things, it determines the queries you need on any page and displays messages according to the specified criteria. It also stores a lot of information about the requests it makes, which helps with page optimization (and error elimination).

WP_Query allows us to perform complex database queries in a secure, simple and modular manner.

Safety

Throughout our interaction with this object, we specify only parameters and use functions to achieve our goal. The internal objects take care of many of the issues themselves, such as protecting against SQL injections and making sure the correct data type is used.

Simplicity

When using this object, we do not need to learn the specifics of our database. Since we're using an array to pass our parameters, there's no need to manually write join queries or nested queries, just create an array of arguments and an instance of the class!

Modularity

WP_Query allows you to avoid using SQL queries in the code, the class uses an associative array as an argument. This allows you to get a lot of benefits: you can combine arguments from different places in the code, run an array of functions, and manipulate them in all sorts of ways.

So, let's begin!

"Standard" Loop in WordPress

Let's look at a regular loop first, and then create the same loop using WP_Query. Let's assume we are creating a category.php file for our theme.

if (have_posts() ) :
while (have_posts() ) :
the_post() ;
?>



endwhile ;
else:
?>
Oops, no entries found!
endif ;
?>

Same loop using WP_Query:

$args = array ("cat" => 4 ) ;
$category_posts = new WP_Query($args) ;

if ($category_posts -> have_posts()) :
while ($category_posts -> have_posts()) :
$category_posts -> the_post () ;
?>



endwhile ;
else:
?>
Oops, no entries found!
endif ;
?>

As you can see, at first glance there is not much difference! Let's take a closer look at it:

Building queries

On the category page, we want to get a list of posts from that category. Since we're building the query from scratch using WP_Query, we have to define this ourselves. We'll get a little deeper into this a little later.

Creating an instance of the class and queries for messages

Using a class instance and an array of arguments, WP_Query will attempt to retrieve the specified messages.

Creating a Loop

You can use any regular functions, just remember to use them as object methods:

Instead of have_posts(), use $category_posts->have_posts().
Instead of the_post(), use $category_posts->the_post().

Once you've done everything above, you can use any of the template tags we know and love.

If you look at this in more detail, you will see that the global object $post also available. This means that if you use a custom loop, things can go wrong. Be sure to preserve the original value of the object $post and restore it after the cycle.

Go ahead...

The ease with which we can create loops is obvious, but how do we actually create queries for records? Let me show you a common method that is often used when creating sliders in commercial themes.

Very often, users of your theme want great-looking sliders on their sites, but they may be a little lazy when creating content. Many users also want to show future posts that are scheduled to be published. Let's create a query to retrieve upcoming (i.e. unpublished) posts that have an image.

$args = array (
"post_status" => "future" ,
"meta_query" => array (
array (
"key" => "_thumbnail_id" ,
"value" => "" ,
"compare" => "!="
)
) ;
$slider_posts = new WP_Query($args) ;
?>

have_posts () ) : ?>


have_posts () ) : $slider_posts -> the_post () ?>




Short and completely understandable code - simple and beautiful.

Default values

You may have noticed that I did not specify the number of required records in my request. How many messages are in the list? And what is the status of the post in the first request we made?

Default values ​​are set for many of the most common arguments. Here are a few that you don't have to specify unless you want to change them:

posts_per_page
By default, the value specified in the site parameters for the number of messages on the page is used.

post_type
Default is post.

post_status
Default is publish.

You can find a complete list of parameters in the documentation!

Arrays

In many cases, you will need to specify multiple values ​​that the argument can take. And WP_Query allows you to use arrays to make your life easier. Here are some examples:

You can use an array for post_status to receive messages with different statuses. Note that you can use the line any to receive messages with all kinds of statuses.

Working with metadata

Have you already seen that WP_Query handles metadata great - we used meta_query in the second example, when we built a slider with posts that have images.

Let's imagine that we are creating a WordPress theme that will be used for a website for renting out an apartment(s). We will store apartments in a custom post type and use metadata to store additional information. In this way we can easily obtain, for example, all apartments that can accommodate four or more people, or those that have a balcony, or only apartments for the day with a jacuzzi.

$args = array (
"post_type" => "apartment" ,
"meta_query" => array (
"relation" => "AND" ,
"=" => "="
)
) ;
?>

To learn more about the parameters that can be used, simply check out the Custom Field Parameters section of the WP_Query documentation.

Methods and properties

Once you have made a request, you can extract a lot of information from your object. You can find a complete list of "Methods and Properties" in the documentation. Here are the ones I like to use most often:

$query
Shows the query string that is passed to the $wp_query object. This is very useful for troubleshooting in some cases.

$query_vars
Shows an associative array of the arguments you passed. If you do a lot of mixing and matching before passing arguments, this tool can be useful to check that everything is passed correctly.

$post
Contains the requested records from the database.

$found_posts
A handy thing that shows the total number of elements found (without the limit set by the posts_per_page argument).

With great power comes great responsibility

WP_Query gives you great power, but it has its drawbacks. Many people go crazy when they realize how easy it is to call queries everywhere.

Keep in mind that the more requests, the greater the load on the server. When creating complex queries, you may run into problems with your hosting RAM, which is likely a limited resource you have.

Make sure the default query runs on every page. What's the point of creating a new query to get the latest posts on the home page if it's there by default? Use result caching to reduce server load.


If you have any questions, we recommend using our