![](/assets/images/2024/query-loop-sorting.webp)
Hacking the Query Loop
I've been loving building sites with the block editor and more recently sites with full site editing (FSE). One thing I've run into a few times is the need to hack the Query Loop block with some additional filtering and sorting.
I've been loving building sites with the block editor and more recently sites with full site editing (FSE).
One thing I've run into a few times is the need to hack the Query Loop block with some additional filtering and sorting.
Both time were event related. For the latest site, we created an event type using Pods Framework, storing the fields as postmeta.
For events, you'll want to sort by a date, like start_date and sometimes files past events.
The query loop supports a search field. I've been using that to hack the loop with sorting and filtering. The basic idea is to intercept the query and split it into other supported query options.
For example: order:asc|orderby:start_date|meta_key:start_date|meta:start_date;$today;<
That command, will set the order
, orderby
, and meta_key
for sorting. Then the meta key, will do a meta_query
filtering for start_date
less than $today
.
$today
is a special value that gets today formatted as yyyy-mm-dd
.
Add the following to the functions.php
file in the child theme.
add_action( 'pre_get_posts', function( \WP_Query $query ) {
if ( $query->is_search() && str_contains( $query->get( 's' ), ":" ) ) {
// Editor html encodes <
$args = html_entity_decode($query->get( 's', '' ));
// echo "Args: " . $args . "<br>";
// Clear search query
$query->set( 's', '' );
$commands = preg_split( "/\|/", $args );
// Loop through filters
// order, orderby, s, post_type, posts_per_page, paged, meta_key
foreach ( $commands as $command ) {
// Split filter into key and value
$command = preg_split( "/:/", $command );
$key = $command[0];
$value = $command[1];
if ( $key === 'meta' ) {
$params = preg_split( "/;/", $value );
$param_key = $params[0];
$param_value = $params[1];
$param_compare = $params[2];
if ( $param_value == '$today' ) {
$param_value = date( 'Y-m-d' );
}
// echo "Adding: " . $param_key . " " . $param_compare . " " . $param_value . "<br>";
$query->set('meta_query', array(
array(
'key' => $param_key,
'value' => $param_value,
'compare' => $param_compare,
),
));
} else {
// Add command to query
$query->set( $key, $value );
// echo "Adding: " . $key . " => " . $value . "<br>";
}
}
}
} );
Definitely not exhaustive or super intuitive, but it gets the job done and is usable for any Query Loop.
Webmentions
These are webmentions via the IndieWeb and webmention.io. Mention this post from your site: