Drop-down search options, dBaines.com 2011

I like having an easy-to-use search bar that isn't redundant and doesn't require several different search bars to do things that a single search bar should be able to do. PhpBB, I'm looking at you.

Today I'll teach you how to add some options to your WordPress search bar to search for several different things. The search bar will allow the user to search:

  • All post types and categories
  • Only blog post types
  • Only portfolio post types (which in this example will be an array of three different kinds of post types in itself)
  • Only in the tutorial category

Set up your search bar as you normally would in your template. For this example, I'm just going to have a search bar on an empty page, for simplicity's sake.

Modifying your template

Open up the template that has your search bar in it. Your search form should look something like this:

 
<form id="search" name="searchform" method="get" action="<?php bloginfo("url"); ?>">
<section id="searchMain">
<input type="search" id="s" name="s" title="Search Blog" placeholder="Search My Website" />
<button type="submit" value="search" id="searchsubmit">Search</button>
</section>
</form>
 
Fig. 1 - Your Form So Far

Here I've used a HTML5 element called section to wrap around my form elements. You can use a div if you're not comfortable using HTML5 elements. We need a container element for these elements because the options are going to be in a separate container, but still in side the form.
Create another section element underneath the searchMain section, and call it something like searchOptions. Populate this element with some radio buttons and some labels, as you would if you were setting up any old regular form with a radio selection. The "name" for these radio buttons will be "post_type". Set up the values to represent what you would like the post_type to be when the user searches. My code at this point is now looking like this:

 
<form id="search" name="searchform" method="get" action="<?php bloginfo("url"); ?>">
<section id="searchMain">
<input type="search" id="s" name="s" title="Search Blog" placeholder="Search My Website" />
<button type="submit" value="search" id="searchsubmit">Search</button>
</section>
<section id="searchOptions">
<input type="radio" value="all" name="post_type" id="searchOptionsAll" checked /> <label for="searchOptionsAll">Search All</label><br />
<input type="radio" value="post" name="post_type" id="searchOptionsBlog" /> <label for="searchOptionsBlog">Search Blog Only</label><br />
<input type="radio" value="portfolio" name="post_type" id="searchOptionsPortfolio" /> <label for="searchOptionsPortfolio">Search Portfolio Only</label><br />
<input type="radio" value="tutorials" name="post_type" id="searchOptionsTutorials" /> <label for="searchOptionsTutorials">Search Tutorials Only</label>
</section>
</form>
 
Fig 2 - The Search Options!

Note: I've added the "checked" attribute to the first radio button. This will act as the default action. This way you don't need to worry about coding in a fallback in case someone doesn't select an option.
If you would like a different option to be used as the default search, remove the checked attribute from the first radio button and add it to the one you want to be the default.
So now we've got a pretty good looking form coming together.

Functions.php

You've got a pretty swanky form going now, but does it actually do anything? If you click search, you'll notice it sends ?s=%searchterm%&post_type=%yourselection% to the search results page up in the URL. We're now going to take advantage of those GET variables and do some pretty cool things with them.

Open up your functions.php and at the bottom, paste in the following code:

 
/***********************************
*
* SEARCH FILTER
* http://speckyboy.com/2010/09/19/10-useful-wordpress-search-code-snippets/
*
***********************************/
function SearchFilter($query) {
if ($query->is_search or $query->is_feed) {
// Portfolio
if($_GET['post_type'] == "portfolio") {
$query->set('post_type', array('artwork', 'websites', 'motion'));
}
// Tutorials
elseif($_GET['post_type'] == "tutorials") {
$query->set('category_name','tutorials');
}
// EVERYTHING! MWAHAHAHAHAHA
elseif($_GET['post_type'] == "all") {
$query->set('post_type', array('artwork', 'websites', 'motion', 'post'));
}
}
return $query;
}
// This filter will jump into the loop and arrange our results before they're returned
add_filter('pre_get_posts','SearchFilter');

I like to always attribute links to the places I find the snippets of code I use, so you'll notice I've included a link to the site where I originally found the snippet we'll be using today.
I've added two checks, the first one checks if the page we're on is a search, the second one checks if we're looking a feed. The feed part is optional and you can remove it. I included it because I also wanted to have these queries available as custom feeds.

Once the feed or search check is confirmed, it will move on to look at the $_GET values for the "post_type" variable:

  • If it finds "portfolio" it will create a custom query to return all posts in the "artwork", "websites" and "motion" post types that match the search terms. These are proper custom post types I had previously set up in the back-end using the Custom Post Type UI plugin.
  • If it finds "tutorials" it will create a custom query to return all posts in the tutorials category that match the search terms.
  • if it finds "all" it will create a custom query similar to the first one, however instead of just returning those three post types, it also returns "post" post types, which are the default blog post types for WordPress. This way you're essentially searching all four post types for the same term.

Notice I didn't need to set up a custom query for the "Search blog only" option. If you look back at the code for the radio buttons, the value it sends is simply "post". As we've learned in the code snippet above, "post" is the post type for the default WordPress blog posts. The variable the search form sends to the search results page is post_type, which is actually a real variable you can pass to WordPress at any time. As such when you search only the blog it will send ?post_type=post to the search results page and WordPress will know exactly what to do with this out of the box.

Now you'll probably want to change the post_types above to use the post_types you want to search for on your own WordPress install. Unless you find yourself in the incredibly coincidental scenario of having exactly the same sort of post types as me. In which case, high five!

So now your search form should be fully functional and ready to go!

Some jQuery magic

If you're like me, you like a search bar to not take up too much room, and be fairly easy to access. These new options seem to take up a lot of space and don't look very good. What can we do about that? Well, how about we add a show/hide options button? Sounds pretty good to me!

Go back to your search form template and add in a link just after the search button. Make sure to give it a unique ID so we can target it in jQuery later. Here I've called mine searchAnchor:

  <section id="searchMain">
<input type="search" id="s" name="s" title="Search Blog" placeholder="Search My Website" />
<button type="submit" value="search" id="searchsubmit">Search</button>
<a href="#" id="searchAnchor">Search Options</a>
</section>
Figure 3 - Complete Form with New Link

Okay, great. Now we have a little link there. If you already have a scripts file with other jQuery business in it, open that up. If not, create a scripts.js file and dump it in to your theme folder. Enter in the following code:

$(function() {
$("#searchAnchor").click(function(){
$("#searchOptions").toggle();
});
});

Make sure you link up your new scripts.js file to your theme, then try it out! Now when you click the link it hides the options. Clicking it again shows them again! Woo! But we'll probably want it hidden by default. So open up your CSS file and add the following:

 
#searchOptions {display: none;}
 

Lookin' good, good lookin'. Now it's hidden by default, and clicking on the "search options" link shows them. Now all that's left is to style that puppy up. Add some background colours, borders and all sorts of crazy CSS3 goodness and you'll soon end up with a pretty swanky lookin' form.

Drop-down search options, dBaines.com 2011

If I'm still using the db2011 theme while you're reading this then there should be a live, working demo right there in the top right corner of this very website!