I'm trying to load/utilise an existing page template (templates/results.php) while making use of the "s" (search) query parameter. For example: example.com/results?s=lorem
Currently, this results in a 404.
I've got a filter using template_includes
, however it appears that the page has already been "decided" before that hook/filter (is_search()
, is_page('results')
are both false) before loading the template. I could just load the template files based on some other parameters, but then I'd have to set the title and other things away from the 404 page.
The pagename
and s
fields are recognised in the global $wp_query
's raw query vars, so it'd just be a case of "deciding" what the query actually is before the template is hit.
Usecase for this being able to show a filtered set of posts for a custom post type "listings". The Listings archive already shows listings, automatically filtered for "open" ones, and optionally filtered for its taxonomy and "s" for any searches. I'd have the results page do the same thing, being able to pick up the same optional query parameters as its archive counterpart.
How can I load a page, and utilise an existing page template while still using the in-built s
query parameter?
This answer's solution 1 mentions replacing the default 's' query var with a custom one, aiming to avoid that and hopefully filter/hook in before WordPress decides to search the results page for the 's' string.
How the page/query are currently used:
Template file:
<?php
// get_header() and the_post() related parts have already been called in the main template file.
// Temporary query to replace the main one so we can utilise pagination, etc.
global $post;
global $wp_query;
$listing_results_query = new WP_Query( [
'listing_type' => get_query_var( 'listing_type' ),
'pricing' => get_query_var( 'pricing' ),
's' => get_query_var( 's' ),
'paged' => get_query_var( 'paged', 1 ),
'post_type' => 'listing',
'query_id' => 'listing-results',
'listing_status_compare' => '!='
] );
$temp_query = $wp_query;
$wp_query = NULL;
$wp_query = $listing_results_query;
?>
<span>Various HTML and get_template_part() calls being used to load the archive</span>
<?php
// Reset main query object
$wp_query = NULL;
$wp_query = $temp_query;
?>
Hook/function file (equivalent of functions.php)
I've cut some checks/other query parts out to simplify it for here. At the point of calling this hook (pre_get_posts), $query->is_404
is already set to true
.
function wpse_390935_modify_listing_archive_query( $query ) {
$is_listing_archive_results = ! is_admin() && ( $query->query['query_id'] ?? false ) === 'listing-results';
if ( $is_listing_archive_results ) {
$page_no = $query->query['paged'] ?? 1;
$listing_type = $query->query['listing_type'] ?? '';
$pricing = $query->query['pricing'] ?? '';
$search = $query->query['s'] ?? '';
$status_compare = $query->query['listing_status_compare'] ?? '=';
$meta_query = [];
// Search
if ( $search ) {
$query->set( 's', sanitize_text_field( $search ) );
}
// Other custom field/taxonomy query bits
}
}
add_action( 'pre_get_posts', 'wpse_390935_modify_listing_archive_query', 10, 1 );
search.php
template file (which is loaded automatically by template hierarchy conventions) to load your file. Orrrrr... maybe I've misinterpreted the question.WP_Query
from parsings
into the main query args. That or maybe a rewrite to a different query var, so it appears ass
to the end user but is something else internally.s
query var? Do you use a secondaryWP_Query
orget_posts()
or some such in there?