You don’t need to! With a little understanding of how URLs and query vars work, we can do this entirely within the URL of the page, with no additional PHP code
First we have a URL:
example.com/abc/123
Then we have a rewrite rule. The rule has a regex pattern that matches the URL, and a second bit that says were all the bits that match go, e.g.
"/abc/(.+)" -> "index.php?p=$match[1]"
This gives converts /abc/123
into index.php?p=123
, which becomes WP_Query( array( 'p' => 123 ) )
. WordPress then takes a look at the new WP_Query
, makes it the main query ( the post loop ), and does a little bit of logic to decide which template to load. In this case it sees the p
and declares this to be a singular
page, so single.php
will probably be loaded. See the template hierarchy for more details on that.
The important part is, we can pass extra parameters! /abc/123
matches, but so does /abc/123?s=test
. This results in index.php?p=123&s=test
, and WP_Query( array( 'p' => 123, 's' => 'test'))
.
Since s
is the search query param, we can use this new found knowledge to do what you need!
So lets say your user is in the tshrit category, which has the URL:
example.com/product-category/tshirts
We can use
example.com/product-category/tshirts?s=test
Now we have a search of the tshirts product category for ‘test’. This is great because now we have a URL that’s always a search of that category. We could have tracked the tshirt category in a cookie or a session, but this would lead to a single URL showing multiple things to different people, and all the caching problems and SEO issues that come with it.
How would we build the search form?
<form action="" method="get">
<input type="text" name="s" value="<?php echo get_search_query(); ?>">
</form>
Notice 2 things:
- The text input has the name
s
- We want to submit the page we’re currently on. We could do PHP voodoo to get the current URL, but we don’t need to, so we set the
action
attribute to nothing, and let the browser handle it - I specified the value so that you know what it was you just searched for using
get_search_query
- This won’t work with
POST