I have three separate search boxes on my website: species
CPT search, glossary
CPT search and a general search which I’d like to search post
and species
post types.
My questions are threefold,
- What’s the most efficient/effective code to make pretty search URLs, and is there a reason that WordPress doesn’t activate these by default?
- Bearing #1 in mind, what code do I need to use in
searchform-species
,searchform-glossary
,search
andsearchresults
to specify that my species search will only return species results, glossary will return glossary results, etc. - How do I incorporate pagination?
The code I’m currently attempting is as follows:
CODE FOR #1
add_action( 'template_redirect', 'my_rewrite' );
function my_rewrite() {
if ( is_search() and false === strpos( $_SERVER['REQUEST_URI'], '/search/' ) ) {
wp_redirect( get_bloginfo( 'home' ) . '/search/' . str_replace( ' ', '+', str_replace( '%20', '+', get_query_var( 's' ) ) ) );
exit();
}
}
CODE FOR #2 & #3
searchform.php
<?php
$search_query = get_search_query();
if (!$search_query) {
$search_query = "SEARCH";
}
?>
<form id="topbar_search" action="<?php echo home_url( "https://wordpress.stackexchange.com/" ); ?>" method="post">
<p>SEARCH</p>
<input type="text" size="50" value="<?php echo $search_query; ?>" name="s" id="s" class="topbar_longinput default-value" />
<input type="submit" value="GO" class="topbar_submit" />
<p class="tinylinks"><a href="#1">advanced search</a></p>
</form>
searchform-species.php
<h1 class="profilesearch">PROFILE<span class="white">SEARCH</span></h1>
<form id="profilesearch" action="<?php echo home_url( "https://wordpress.stackexchange.com/" ); ?>" method="post">
<input type="hidden" name="type" value="profile" />
<input type="text" size="50" class="default-value" value="SEARCH" name="s" />
<input type="submit" value="GO" class="profilesearch_submit" />
<!-- <p class="tinysearch"><a href="https://wordpress.stackexchange.com/dev/advanced-search/">ADVANCED SEARCH</a></p> -->
<input type="checkbox" name="showthumbnails" id="showthumbnails" class="checkbox" <?php if ($_POST["showthumbnails"] == "on") { echo 'checked="checked" '; } ?>/><label for="showthumbnails">HIDE THUMBNAILS</label>
</form>
search.php
if (isset($_REQUEST["type"])) {
switch ($_REQUEST["type"]) {
case "profile" :
$post_type = "species";
break;
case "glossary" :
$post_type = "glossary";
break;
default :
$post_type = array( 'post', 'species' );
break;
}
} else {
$post_type = array( 'post', 'species' );
}
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$args = array(
's' => $search_term,
'post_type' => $post_type,
'paged' => $paged
);
?>
<?php get_template_part('searchresults'); ?>
What’s currently happening is this:
The individual searches work, but the pagination doesn’t. When I click my next/previous_posts_link
button, it adds /page/2/
to the URL and does nothing. If I try to echo out the get_query_var('page')
it returns NULL
. If I try to echo out 'paged'
instead, it returns 0
.
Additionally when a user clicks this link, the $search_query
variable from searchform.php is displaying as page/bettas
(where bettas
is the original query).
Ideally what I’d like to happen is this:
- In the “general search”, a user enters betta. The URL changes to
/search/betta
which lists anypost
orspecies
content containing the word betta. - In the “species search”, a user enters betta. The URL changes to
/search/betta/species
(or whatever is best for SEO) and displays a list of onlyspecies
content containing the word betta. - The same user as #2 then clicks the Next button (
previous_posts_link
). The URL changes to/search/betta/species/page/2
and the user gets to see the next 25 species listed.
I’m a complete novice at WP rewriting and pagination so any assistance would be greatly appreciated.
1 Answer
Pagination can be done in exactly the same way it works everywhere else in the search archive template.
There’s no need for your custom query and type variable in search.php either. To search for a particular custom post, you can either modify the query, or you can go to that posts archive and append the search query, e.g.
example.com/event_post_type/?s=term
The same is true of any category or taxonomy archive, simply adding ?s=searchterm on the end will turn it into a search query, just like adding /feed/ to the end of URL will give you an RSS2 feed for that particular page/archive content.
You’re task in prettifying this would involve adding an extra rewrite rule to convert that into something nicer, e.g.:
function search_rewrite( $wp_rewrite ) {
$feed_rules = array(
'search/(.+)/events' => 'index.php?post_type=events&s=". $wp_rewrite->preg_index(1)
);
$wp_rewrite->rules = $feed_rules + $wp_rewrite->rules;
}
// refresh/flush permalinks in the dashboard if this is changed in any way
add_filter( "generate_rewrite_rules', 'search_rewrite' );
Would allow you to do example.com/search/searchterm/events, although i advise /events/search/searchterm as a better way of doing it.
Use the monkeyman rewrite rules analyser plugin to test your changes, and you can find more details about rewrite rules in this answer here: Pretty URL with add_query_var