By default, when you search on a WordPress site, your search URL has an /?s= parameter. Back in the old days of WordPress, we all had URLs like /?p=123 where 123 was the page ID. With the advent of Pretty Permalinks, we moved to pretty URLs like /2016/prettier-search-queries/ and everyone was happier.

What about search?

As it happens, the WP Rewrite API actually has a search base of … search. If you go to your Settings > Permalinks page, you won’t see it there, and yet on every site if you go to https://halfelf.org/search/apache you’ll actually get that nice, pretty path.

Because of that, you could get away with adding this to your .htaccess file in order to get those pretty URLs.

RewriteCond %{QUERY_STRING} s=(.*)
RewriteRule ^$ /search/%1? [R,L]

You can also use a plugin like Mark Jaquith’s Nice Search.

Those methods work for nearly all sites.

But you know me. I’m not ‘all’ sites.

Extra Paramater Headache

I had a different problem. Because my site had specialized data, it had extra search parameters. I was intentionally limiting my search to specific post type. This meant my URLs looked like this: /?s=rookie+blue&post_type[]=post_type_shows

When I translated that to use the pretty search, well …/search/rookie+blue&post_type[]=post_type_shows just didn’t work.

This is for a pretty obvious reason when you study the URLs. The first one has ?s=... and then later an &, while the second only has the & in there. If I changed the URL to this, it worked: /search/rookie+blue/?post_type[]=post_type_shows

The reason for this was due to how parameters work in URLs. They have to start with ? at the beginning. All additional parameters are added with ?param=value after that.

Semi Pretty Search Permalinks

To me, the nicest URLs would be `/search/rookie+blue/section/shows/’. The reality is that people will search shows and characters and I wasn’t quite sure how I wanted to handle that. Did I want them to be sections separated by plus signs, or extra ‘folders’ or what? In the end, I decided that for now it was okay to just make these prettier.

Taking Mark’s code as my start point, I came up with this:

function pretty_permalink_search_redirect() {
	// grab rewrite globals (tag prefixes, etc)
	// https://codex.wordpress.org/Class_Reference/WP_Rewrite
	global $wp_rewrite;

	// if we can't get rewrites or permalinks, we're probably not using pretty permalinks
	if ( !isset( $wp_rewrite ) || !is_object( $wp_rewrite ) || !$wp_rewrite->using_permalinks() )
		return;

	// Set Search Base - default is 'search'
	$search_base = $wp_rewrite->search_base;

	if ( is_search() && !is_admin() && strpos( $_SERVER['REQUEST_URI'], "/{$search_base}/" ) === false ) {

		// Get Post Types
		$query_post_types = get_query_var('post_type');
		if ( is_null($query_post_types) || empty($query_post_types) || !array($query_post_types) ) {
			$query_post_types = array( 'post_type_characters', 'post_type_shows' );
		}

		$query_post_type_url = '/?';
		foreach ( $query_post_types as $value ) {
			$query_post_type_url .= '&post_type[]=' . $value ;
		}

		wp_redirect(
			home_url( "/{$search_base}/"
			. urlencode( get_query_var( 's' ) )
			. urldecode( $query_post_type_url )
			) );
		exit();
	}
}
add_action( 'template_redirect', 'pretty_permalink_search_redirect' );

And that actually does work exactly as I want it to.

Reader Interactions

%d bloggers like this: