v2 Documentation
Queries / Chainable Methods
Now that we know how this whole thing works, how to chain, and how to get results, let's go over all chainable methods at your disposal.
Arguments
As you read through this page you'll see many helpful methods that are all chainable to create a kick@$$ query. Sometimes though you may want to interact directly with these arguments. To do that, use setArgs
or setArg
. Behind the scenes WPM is creating a get_posts
or WP_Query
so you'll recognize these parameters.
->setArg()
You can overwrite an argument that WPM has built up for you by using setArg
. This can be helpful if you need to manually tweak a value.
// manually set an argument
$posts = wpm('q.member')->setArg('perm', 'readable')->get();
->setArgs()
You can overwrite all arguments that WPM has built up for you by using setArgs
. I can honestly say, I've never needed to do this but you have the option. Pair with getArgs to return all your arguments and then replace a few.
// it exist
$args = wpm('q.member')->metaValue('pink')->getArgs();
$args['meta_value'] = 'blue';
$args['meta_key'] = 'color';
$posts = wpm('q.member')->setArgs($args)->get();
Cache
->cache()
WordPress caches the results of your queries automatically. Because of this there is no reason to turn caching on, however, if you find a reason to turn off the caching of your results you can use cache
to do so.
// don't add posts to the cache
$results = wpm('q.post')->year(2010)->cache(false)->get();
// don't add meta to the cache
$results = wpm('q.post')->year(2010)->cache('meta', false)->get();
// don't add terms to the cache
$results = wpm('q.post')->year(2010)->cache('term', false)->get();
Category
->category()
Posts, as in blog posts, can be queried by categories. category
takes 1 - 2 arguments. You can define the categories you are getting results for by id, category slug, or an array of either category ids or slugs.
/*
* Match all given categories
*/
// get by category slug
$posts = wpm('q.post')->category('photography')->get();
// get by category id
$posts = wpm('q.post')->category(45)->get();
// get by an array of category slugs
$posts = wpm('q.post')->category(['photography', 'film'])->get();
// get by an array of category ids
$posts = wpm('q.post')->category([45, 30])->get();
If we need to provide a comparison, we'll send that in as the first argument and the supply the categories as the second. category accepts the following comparisons: and, in, not
/*
* Match provided categories with a given comparison
*/
// return posts that are assigned to nature and hiking
$posts = wpm('q.post')->category('and', ['nature', 'hiking'])->get();
// return posts that are assigned to either running or jogging
$posts = wpm('q.post')->category('in', ['running', 'jogging'])->get();
// return posts that are not assigned to the category with an id of 82
$posts = wpm('q.post')->category('not', 82)->get();
Behind the scenes, category
makes a taxonomy query. While WordPress does allow querying categories without a taxonomy query they aren’t dependable. Read more about chainable taxonomy query methods.
Date & Time
A series of methods that allow you to query by date, time and ranges.
->year()
Get results published in the specified year.
$year_posts = wpm('q.post')->year(2010)->get();
->yearMonth()
To get results from a given month, the year must also be specified.
$dec_posts = swpm('q.post')->yearMonth(2010, 12)->get();
->week()
Get results from a given week. As these methods can be chainable, you can specify year before week.
$week_posts = wpm('q.post')->year(2016)->week(15)->get();
->day()
Get results from a set day from a specified year and month.
$day_posts = wpm('q.post')->yearMonth(2015, 11)->day(5)->get();
->hour()
Get results from a set hour from a specified year, month and day.
$hour_posts = wpm('q.post')->yearMonth(2016, 4)->day(22)->hour(10)->get();
->minute()
Get results from a set minute from a specified year, month, day, hour and minute.
$min_posts = wpm('q.post')->yearMonth(2016, 4)
->day(22)
->hour(10)
->minute(0)
->get();
->second()
Get results from a set minute from a specified year, month, day, hour, minute and second.
$sec_posts = wpm('q.post')->yearMonth(2016, 6)
->day(18)
->hour(8)
->minute(30)
->second(23)
->get();
->date()
Use date when you'd like greater control over date queries to include ranges or would like to write your own date query as allowed by WordPress' date query functionality.
$posts = wpm('q.post')->date([
[
'hour' => 9,
'compare' => '>=',
],
[
'hour' => 17,
'compare' => '<=',
],
[
'dayofweek' => [2, 6],
'compare' => 'BETWEEN',
]
])->get();
Fields
->fields()
fields
is a bit deceptive as WordPress doesn't allow you to specify the actual fields you want returned. There are two options when specifying fields as defined by WordPress: id, parent
With id, only the results ids are returned. parent returns both the ids and their _postparent.
// return the result's ids only
$pages = wpm('q.page')->fields('id')->get();
// return both the ids and the post_parent id
$pages = wpm('q.page')->fields('parent')->get();
WPM will return an object or an array of objects for the result of a given query. fields
is the only instance where WPM will return an array.
Limit
->limit()
Use limit to control the maximum number of results when finishing a query with get() to return all matching results. If you need a brush up, read me or the different ways to get results.
// get a maximum of 3 results
$fruit = wpm('q.fruit')->limit(3)->get();
// get a maximum 10 results
$fruit = wpm('q.fruit')->limit(10)->get();
Meta
Meta queries allow you to define the meta key, value, both, or build a complex query.
->metaKey()
With metaKey
we can query for results that contain a set key regardless of value.
// query for all members that have an age set as a meta field
$members = wpm('q.member')->metaKey('age')->get();
->metaValue()
With metaValue
we can query for results that contain a set value regardless of key.
// query for all members that have any meta value set to pink
$members = wpm('q.member')->metaValue('pink')->get();
->metaValueNum()
metaValueNum
works like metaValue
except it expects the value you are searching for to be a integer instead of a string.
// query for all members that have any meta value set to pink
$members = wpm('q.member')->metaValueNum(36)->get();
->metaCompare()
While metaValueCompare
allows you to set the comparison check between your metaKey
or metaValue
. The default is =. That said, if you're digging this deep you'll probably just want to use the meta
instead.
// query for all members that have any meta value other than pink
$members = wpm('q.member')->metaCompare('!=')->metaValue('pink')->get();
->metaType()
The metaType
is the setter for the meta_type argument. The default is CHAR but other possible values include: NUMERIC, BINARY, CHAR, DATE, DATETIME, DECIMAL, SIGNED, TIME, UNSIGNED.
// query for all members that have any meta value other than pink
$members = wpm('q.member')->metaType('CHAR')->metaValue('pink')->get();
->meta()
We find posts by meta key and value by chaining both its metaKey
and metaValue
methods but that is too much work. meta
allows us to define both and do some comparison when needed. The meta value could be a single integer or string, or an array of integers or strings. If an array is given, a comparison must be specified. Comparisons include:
=, !=, >, >=, <, <=, like, not like, in, not, between, not between, exists, not exists, regexp, not regexp, rlink
// get all members that are exactly 18
$new_voters = wpm('q.member')->meta('age', 18)->get();
// get all member that are 18 or over
$voters = wpm('q.member')->meta('age', '>=', 18)->get();
// get all member whos favorite color is red or purple
$members = wpm('q.member')->meta('color', 'in', ['red', 'purple'])->get();
->andMeta()
If you need to make additional comparisons where both comparisons must be true use andMeta
. andMeta
uses the same 2 - 3 arguments as the meta
method.
// get all voters that are democrats
$dem_voters = wpm('q.member')
->meta('age', '>=', 18)
->andMeta('party', 'democrat')
->get();
->orMeta()
If you need to make additional comparisons where at least one of the comparisons must be true use orMeta
. orMeta
uses the same 2 - 3 arguments as the meta
method.
// get voters that are 18 or older or have special permission
$voters = wpm('q.member')
->meta('age', '>=', 18)
->orMeta('special_permission', 'yes')
->get();
Important
andMeta
and orMeta
can’t be mixed. For more complex queries you’ll want to use metaQuery
.
->metaQuery()
andMeta
and orMeta
can not be mixed so, to make more complex meta comparisons, we can use metaQuery
in combination with meta
, andMeta
or orMeta
. metaQuery
takes the same 2-3 attributes as meta
.
// get voters that that are democrat and are between the ages of 30 and 50
// OR
// get voters that are independent and are between the ages of 18 and 30
// OR
// get voters that are republican and are over 50
$base_voters = wpm('q.member')
->meta(function($wpm) {
return [
'relation' => 'AND',
$wpm->metaQuery ( 'party', 'democrat' ),
$wpm->metaQuery ( 'age', 'between', [ 30, 50 ] )
];
})->orMeta(function($wpm) {
return [
'relation' => 'AND',
$wpm->metaQuery('party', 'independent'),
$wpm->metaQuery('age', 'between', [18, 30])
];
})->orMeta(function($wpm) {
return [
'relation' => 'AND',
$wpm->metaQuery('party', 'republican'),
$wpm->metaQuery('age', '>', 50)
];
})->get();
Mime Type
->mimeType()
With mimeType
, you can specified the types of files you'd like returned in your results by their mime types. This could be either a single type or an array of types.
// show only jpegs
$jpegs = wpm('q.attachment')->mimeType('image/jpeg')->get();
// show both jpegs and gifs
$imgs = wpm('q.attachment')->mimeType(['image/jpeg', 'image/gif'])->get();
Paging
The following are various methods allow you to return results based on the page a result would appear on when paginated.
->paged()
Return results, as if they were paginated, from a given page.
// at 5 posts per page (limit), return results that would appear on page 4
$posts = wpm('q.post')->limit(5)->paged(4)->get();
->page()
This is much like paged
but returns posts as if they were appearing on a static front page. WordPress has some confusing calls, right?! If you do need this functionality, test both paged and page to see which meets your needs best.
// at 5 posts per page, return results that would appear on page 4
$posts = wpm('q.post')->limit(5)->page(3)->get();
->paging()
By passing in false, results will not be paginated. With WPM, you'll get the same result from paging
by just not chaining the limit
method when using ->get()
to return all matching results .
// remove all pagination
$posts = wpm('q.post')->paging(false)->get();
Parent
->parent()
parent
accepts an id or array of ids and returns the children of the given parent id(s).
// get a post's children
$children = wpm('q.page')->parent(174)->get();
// get all children that match any of the parents in the array
$children = wpm('q.page')->parent([5, 174])->get();
Password
->password()
With password
you can remove password protected pages from your results, get only password protected pages, or get all pages with a specified password.
// get all pages that are password protected
$pages = wpm('q.page')->password()->get();
// get all pages that are not password protected
$pages = wpm('q.page')->password(false)->get();
// get all pages with and without passwords (whatever that means!)
$pages = wpm('q.page')->password(null)->get();
// get all pages with the password of "super"
$pages = wpm('q.page')->password('super')->get();
Permission
->permission()
permission
gets posts based on the user's capability:
// get all private pages if the user has permission to read them
$pages = wpm('q.page')->status('private')->permission('readable')->get();
Offset
->offset()
With offset
, you can skip a specified number of posts and return return results after this number. So, if you wanted to get 10 results after the first 3 results that match your query, you would offset by 3.
// skip first 3 results and then return next 10
$pages = wpm('q.page')->offset(3)->limit(10)->get();
Order
Ordering allows us to choose what field we would like to order by (post_title/title, post_date/date, etc) and what direction this field should be sorted (ascending or descending).
When creating a post type with WPM where the new type will be "like" a "post" (read more about "like" in wp.taxonomies), the default order will be by the _postdate field (WordPress shortens this to "date") in the desc direction (highest to lowest) when you query for its results.
When a custom post type is "like" a "page," the default order will be by _menuorder in the asc direction (lowest to highest).
->order()
With order
we can quickly choose both the field and the direction in which this field will be sorted. If we pass in a single argument, this is the direction in which we'd like to sort the default ordering of the post type. If we pass in two arguments, the first is the field we'd like to sort by and the second is the direction in which we should sort this field.
// sort movies by the title (post_title)
$movies = wpm('q.movie')->order('title', 'asc')->get();
// sort movies by the date (post_date)
$movies = wpm('q.movie')->order('date', 'desc')->get();
// sort movies by the order I specified (menu_order)
$movies = wpm('q.movie')->order('menu_order', 'asc')->get();
// pass in a single argument to change the default direction
$movies = wpm('q.movie')->order('asc')->get();
We can also sort by multiple fields. As an example, if we have two movies of the same name, we might want to order the by title and publish date.
$movies = wpm('q.movie')->order([
'title' => 'asc',
'date' => 'desc'
])->get();
->orderBy()
On occasion, the sort direction (asc or desc) may be fine but you would like to change only the field to sort.
// keeps default order direction and changes field to post_title
$movies = wpm('q.movie')->orderBy('title')->get();
Search
->search()
Run a plain text search across your post_title and post_content fields in a given post type.
$jacks_of_all_trades = wpm('q.member')->search('jack')->get();
Status
->status()
The status
represents the post_status field on the "posts" table. Status defaults to publish unless it is changed to another valid option or options:
any, publish, draft, future, pending, private, trash, auto-draft, inherit
// get results regardless of post_status
$videos = wpm('q.video')->status('any')->get();
// get all results that are published
$videos = wpm('q.video')->status('publish')->get();
// get all results that are either draft or pending
$videos = wpm('q.video')->status(['draft', 'pending'])->get();
Sticky
->sticky()
With sticky
, you can choose to display sticky posts in in their default order, show only the stick posts, or not to show them at all.
// ignore sticky posts return at the top, instead show in default order
$posts = wpm('q.post')->sticky(false)->get();
// show only stick posts
$posts = wpm('q.post')->sticky('in')->get();
// do now show any stick posts, even in their default order
$posts = wpm('q.post')->sticky('not')->get();
Tag
->tag()
Posts, as in blog posts, can be queried by their tags. While a category groups posts under broad classifications (ex: Design, Photography, Nature), a tag help provide granular connectivity too detailed to be classified as a category (ex: iso, f-stop, paper, kodak).
tag
takes 1 - 2 arguments. If you want to match all given tags you do not need to supply the second argument. If you'd like to specify a comparison you'll need to use both arguments. Pass tags into this method by either a single tag id or a tag slug, or an array of tag ids or tag slugs.
/*
* Match all given tags
*/
// get by tag slug
$posts = wpm('q.post')->tag('iso')->get();
// get by tag id
$posts = wpm('q.post')->tag(79)->get();
// get by an array slug
$posts = wpm('q.post')->tag(['iso', 'paper'])->get();
// get by an array of ids
$posts = wpm('q.post')->tag([31, 48])->get();
If we need to provide a comparison, we'll send that in as the first argument and supply the tags as the second. tag
accepts the following comparisons: and, in, not
/*
* Match provided tags with a given comparison
*/
// return posts that are assigned to iso and f-stop
$posts = wpm('q.post')->tag('and', ['iso', 'f-stop'])->get();
// return posts that are assigned to either polaroid or kodak
$posts = wpm('q.post')->tag('in', ['polaroid', 'kodak'])->get();
// return posts that are not assigned to the tag with an id of 479
$posts = wpm('q.post')->tag('not', 479)->get();
Taxonomy
There are many ways to query based on taxonomies with q. Here are the methods that make it all happen.
->tax()
tax
will be the first method used in when chaining Taxonomy related methods. tax
requires at least 1 attribute but can take up to 3 when you'd like to further define the comparison (in, and, not, etc). Let's start with 2 attributes.
/*
* Define the taxonomy and term
*/
// get all creatures assigned to the bird term in our animal taxonomy
$creatures = wpm('q.creature')->tax('animal', 'bird')->get();
// get all creatures assigned to the term id of 204 in our animal taxonomy
$creatures = wpm('q.creature')->tax('animal', 204)->get();
// terms can also be provided in an array
$creatures = wpm('q.creature')->tax('animal', ['bird', 'fish'])->get();
$creatures = wpm('q.creature')->tax('animal', [204, 681])->get();
If an array is given in argument 2, results must match all terms in the array. This is an "and" comparision. Sometimes you may want to give an array of terms and provide a comparison. That is when you'll use 3 attributes:
/*
* Defining the taxonomy, comparison and terms
* ->tax(taxonomy, comparison, terms);
*/
// results must assigned to at least oneterms IN the array
$creatures = wpm('q.creature')->tax('animal', 'in', ['bird', 'fish'])->get();
// get all results that are NOT birds
$creatures = wpm('q.creature')->tax('animal', 'not', 'bird')->get();
// get all results that are assigned to term ids 204 and 681
$creatures = wpm('q.creature')->tax('animal', 'and', [204, 681])->get();
All WordPress Taxonomy comparisons are supported. We've just shorted them a bit to make them easier to understand and remember. These include: and, in, not, exists, not exists.
If you're using something like Advanced Custom Fields you'll likely be matching against dynamic term ids. If you predefined terms for use with your theme, may be more inclined to use slug strings (ex: "alert" post type with a taxonomy of "placement" with options like: home, sidebar, etc)
Finally, tax
can accept a completely custom query by sending an array as the first attribute.
$creatures = wpm('q.creature')->tax([
'taxonomy' => 'animal',
'terms' => ['bird', 'fish'],
'field' => 'slug'
])->get();
But... where's the fun in that? ;)
->andTax()
If you need to make different comparisons with the same taxonomy or you may need to make a comparison with a completely different taxonomy where both comparisons must be true use andTax
. andTax
uses the same 2 - 3 attributes as the tax
method.
// find all creatures that are bird or fish ("animal" taxonomy) and are not blue
// or orange ("color" taxonomy)
$creatures = wpm('q.creature')
->tax('animal', 'in', ['bird', 'fish'])
->andTax('color', 'not', ['blue', 'orange'])
->get();
->orTax()
If you need to make different comparisons with the same taxonomy or you may need to make a comparison with a completely different taxonomy where at least one of the comparisons must be true use orTax
. orTax
uses the same 2 - 3 attributes as the tax
and andTax
method.
// find creatures that are bird or insects ("animal" taxonomy),
// or that can fly ("skill" taxonomy)
$creatures = wpm('q.creature')
->tax('animal', ['bird', 'insect'])
->orTax('skill', 'fly')
->get();
Important
andTax
and orTax
can’t be mixed. For more complex queries you’ll want to use taxQuery
.
->taxQuery()
andTax
and orTax
can not be mixed in a query. To make more complex calls with "and" and "or" comparisons, we use taxQuery
in combination with tax
, andTax
or orTax
. taxQuery
takes the same 2-3 attributes as tax
. We use taxQuery
by passing in a closure to tax
, andTax
, or orTax
. The closure will receive a single argument which will be our q
instance.
// get creatures that are birds or insects ("animal" taxonomy) and an fly ("skill" taxonomy)
// OR
// creatures that are squirrels ("animal" taxonomy) and can glide ("skill" taxonomy)
$creatures = wpm('q.creature')
->tax(function($wpm) {
return [
'relation' => 'and',
$wpm->taxQuery('animal', 'in', ['bird', 'insect']),
$wpm->taxQuery('skill', 'fly'),
];
})->orTax(function($wpm) {
return [
'relation' => 'and',
$wpm->taxQuery('animal', 'squirrel'),
$wpm->taxQuery('skill', 'glide')
];
})->get();
If you needed to pass your own variables into a closure, use the use
PHP feature:
// get creatures that are birds or insects ("animal" taxonomy) and an fly ("skill" taxonomy)
// OR
// creatures that are squirrels ("animal" taxonomy) and can glide ("skill" taxonomy)
$animal_slugs = ['bird', 'insect'];
$animal_skill_slug = 'fly';
$creatures = wpm('q.creature')
->tax(function($wpm) use ($animal_slugs, $animal_skill_slug) {
return [
'relation' => 'and',
$wpm->taxQuery('animal', 'in', $animal_slugs),
$wpm->taxQuery('skill', $animal_skill_slug),
];
})->orTax(function($wpm) {
return [
'relation' => 'and',
$wpm->taxQuery('animal', 'squirrel'),
$wpm->taxQuery('skill', 'glide')
];
})->get();