First, keep in mind that pre_get_posts
is a hook that is run on every single query that WP runs, so be very, very careful when utilizing it. That said, it is absolutely the best tool for what you want to do, and certainly better than writing a separate custom query in the page template.
I’ve added some additional conditions to the start of this function to make sure it is abandoned early if the query is: not for the main loop, running on an admin page, or if the ‘type’ query string is not present. You should add a few more conditions here to restrict it even further, e.g. if ( ! is_page( 'something' ) ) { return; }
or if ( ! is_front_page() ) { return; }
.
That said, here is some sample code:
/**
* Add custom meta filter to main query on any page.
*
* @since 1.0.0
*
* @param object $query WP Query object.
*/
function wpse129223_custom_meta_query( $query ) {
// If not on the main query, or on an admin page, bail here
if ( ! $query->is_main_query() || is_admin() ) {
return;
}
// If 'type' isn't being passed as a query string, bail here
if ( empty( $_GET['type'] ) ) {
return;
}
// Get the existing meta query, cast as array
$meta_query = (array) $query->get('meta_query');
// Convert 'type' into an array of types
$types = explode( ',', $_GET['type'] );
// Ensure that types aren't empty
if ( is_array( $types ) && ! empty( $types ) ) {
// Build a meta query for this type
$meta_query[] = array(
'key' => 'type',
'value' => $types,
'compare' => 'IN',
);
// Update the meta query
$query->set( 'meta_query', $meta_query );
}
}
add_action( 'pre_get_posts', 'wpse129223_custom_meta_query' );
This expects the query string to be comma-separated, as you presented it in your example, website.com/whatever/?type=one,two,three. In your code example you were looking for a pipe character, which is what @Foxsk8 was getting at in his comments.