I am trying to create a custom search page to show only custom posts types that meet specific search criteria. I have a complex form that involves different selects, radio buttons and text input fields. I am comfortable using the WP_Query class to query for the posts that are identified via the search form, but I’m not sure if I should create additional templates or use the built in search page.
Let me give you a for instance to help communicate my conundrum. Imagine you have the CPT “Person”. For each person, you have “Birth Date”, “Gender”, “Height”, and “Weight”. You want to search for all males born after 1972, who are taller than 6 feet tall. How would you work out this search? Again, I can easily put together $args
for the WP_Query class to get these posts. I need to know the best way to integrate this with WordPress.
Ultimately, I need a solution the satisfies the following:
1) Preserves pagination on the search page
2) Only searches for the specific CPT, not other CPTs
And, I have the following questions
1) Should I have a separate template for this, or can I integrate this directly with search.php
? My current solution feels hacky and I would like to develop an alternative. I have created a new Page in the WP admin. I use this page’s URL as the action
attribute in the search form. I then use a custom template to display results of that page. This seems wrong to me.
2) If I integrate this with search.php
how do I preserve the regular search results, in addition to having these lovely custom search results?
Thank you so much for your help!
EDIT: On further investigation, I’m beginning to think that pre_get_posts
will likely be involved in a “better way” to do this.
I found a way to make this work. I was right with the thought that
pre_get_posts
was the way to go. First, I added an action:Then I added the function. This function first checks that the context is correct. In my custom search form, I use a nonce. The nonce helps me verify that it’s my custom search that is being run, not the built in search. I then manipulate the query variables that will be sent to the query. I’m showing my full function here, which includes all of the validation and sanitization of variables, as well as how the query is manipulated: