orderby
is the argument passed to WP_Query
to tell it what column to sort on when it is creating the ORDER BY
clause for its generated SQL. The default value for orderby
is post_date
.
The default sort order for a column in MySQL MySQL is a relational database management system. A database is a structured collection of data where content, configuration and other options are stored. https://www.mysql.com/. is ASC
(ascending), with smallest values first. For the reverse, DESC
is used. You can sort on multiple columns, and each column can have its own sort order.
The default value for the order
argument inside WP_Query
is DESC
. ~23% of the internet automatically queries posts in reverse chronological order because of this. order
can only be one of 2 values: DESC
or ASC
.
orderby
accepts a string, representing a column on which to sort:
$q = new WP_Query( array( 'orderby' => 'post_title' ) );
// or an alias
$q = new WP_Query( array( 'orderby' => 'title' ) );
Both will produce an ORDER BY
clause like:
ORDER BY post_title DESC
orderby
will also parse a space-delimited set of columns:
$q = new WP_Query( array( 'orderby' => 'title author' ) );
Prior to 4.0, there was a problem: the value for order
would only be applied to the last value that you passed in that space-delimited list, producing an ORDER BY clause like:
ORDER BY post_title, post_author DESC
Remember that the default sort order for a column in MySQL is ASC
, so queries like that can get weird real fast and produce unexpected/unpredictable results. If no value is passed for order for a column in the generated SQL, the column will be sorted in ASC
order. This was not so clear to all developers. #26042 was a joy to debug.
In 4.0, when you pass a space-delimited set of values, your sole value for order
will be applied to all of your values that are parsed for orderby
. This was fixed in [28541].
So that’s pretty good, but it doesn’t allow you granular control over the sort order for each column. The syntax doesn’t allow itself much room for extending.
Enter [29027].
In 4.0, you can now pass an array to WP_Query
as the value for orderby
. The syntax looks like:
$q = new WP_Query( array( 'orderby' => array( 'title' => 'DESC', 'menu_order' => 'ASC' ) ) );
This allows you to control the generation of the ORDER BY
clause with more specificity:
ORDER BY post_title DESC, menu_order ASC
Pre-4.0, you would have had to use some gnarly filters on the SQL statement or a specific clause. No bueno.
To see the internals, check out the new protected
methods in WP_Query
: ->parse_order()
and ->parse_orderby
.
Happy WP_Query
ing!
#4-0, #dev-notes, #query