Skip to content

Instantly share code, notes, and snippets.

@JodiWarren
Last active August 29, 2015 14:06
Show Gist options
  • Save JodiWarren/72a876c7f2b7c10ab1cf to your computer and use it in GitHub Desktop.
Save JodiWarren/72a876c7f2b7c10ab1cf to your computer and use it in GitHub Desktop.
Wordpress sort by meta key on date archive
<?php
add_action( 'pre_get_posts', 'sort_by_custom_field' );
function sort_by_custom_field( $query ){
// Make sure we're on the front end, that we're dealing with the main query and that we're on the post type archive for the product custom post type. Also that at least a year is set.
if ( is_admin() || ! $query->is_main_query() || ! $query->is_post_type_archive( 'product' ) || ! $query->is_date() ) {
return $query;
}
// Could shrink this down a lot, but let's be readable.
$defaultYear = 2014;
if ( isset( $query['query']['year'] ) ) {
$queryYear = $query['query']['year'];
} else {
$queryYear = $defaultYear;
}
$outputFormat = 'Ymd';
// The DateTime object stuff here looks scary if you're not used to it, but it's really not too bad.
if ( $query->is_year() ) {
$dateObj = DateTime::createFromFormat( '!Y', $queryYear );
$queryStart = $dateObj->adjust( 'First day of the year' )->format($outputFormat);
$queryEnd = $dateObj->adjust( 'Last day of the year' )->format($outputFormat);
$queryValue = array( $queryStart, $queryEnd );
$queryCompare = 'BETWEEN';
}
// make sure it's a monthly query and that a month is set.
if ( isset( $query['query']['monthnum'] ) ) {
$queryMonth = $query['query']['monthnum'];
}
if ( $query->is_month() && $queryMonth ) {
$dateObj = DateTime::createFromFormat( '!Ym', $queryYear . $queryMonth );
$queryStart = $dateObj->adjust( 'First day of the month' )->format($outputFormat);
$queryEnd = $dateObj->adjust( 'Last day of the month' )->format($outputFormat);
$queryValue = array( $queryStart, $queryEnd );
$queryCompare = 'BETWEEN';
}
// make sure it's a day query and that a day is set.
if ( $query->is_day() && isset( $query['query']['day'] ) ) {
$dateObj = DateTime::createFromFormat( '!Ymd', $queryYear . $queryMonth . $query['query']['day'] );
$queryValue = $dateObj->format($outputFormat);
$queryCompare = '=';
}
// Sort by meta value: http://codex.wordpress.org/Class_Reference/WP_Query#Order_.26_Orderby_Parameters
//
// Select items which have a meta_key of release_date, where it's between Jan 01 2014 and now.
// Times would have to be stored in the format YYYYMMDD for this method.
//
// Then order descending by release date and then ascending by title
$query->set( 'orderby' , array( 'meta_value_num' => 'DESC', 'title' => 'ASC' ) );
if ( ! isset( $queryCompare ) || ! isset( $queryValue ) ) {
return $query
}
$query->set( 'meta_key' , 'release_date' );
$query->set( 'meta_query' , array(
array(
'key' => 'release_date',
'value' => $queryValue, // this will either be the exact day or the range of dates applicable
'type' => 'DATE',
'compare' => $queryCompare, // This will either be BETWEEN or =
),
)
);
return $query;
}
@JodiWarren
Copy link
Author

This is quite verbose for readability.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment