Canine: WordPress Custom Searches

The WordPress search by default looks through the title and content of all available posts and pages for given query words. But sometimes you might want to only search a certain category or search custom fields or some other criteria. On the Canine Lifeline site, we have a dog section where we want to be able to list dogs based on a number of parameters, such as age, gender, adoption status, et cetera. We are currently storing dogs as posts in a particular category, and using Magic Fields to add custom fields for various aspects of each dog.

WordPress sends search queries as GET requests from its search form. The “s” variable contains the search query, but others are allowed. In fact, if you’re familiar with the “query_posts” function, many of the parameters for that are available, and the rest can be enabled, because the search is basically just a regular WordPress query with parameters appended from the GET variables.

To modify the search functionality, you can simply add fields to your search form with the names of the parameters you want to search with, like:

<div class="search dogs">
	<form role="search" method="GET" action="<?php bloginfo('siteurl'); ?>/">
		<label class="screen-reader-text" for="s">Search dogs:</label>
		<input type="text" value="<?php echo $_GET['s']; ?>" name="s" id="s" />
		<input type="hidden" name="cat" value="3" />
		<input type="submit" id="searchsubmit" value="Search" />
	</form>
</div>

This does a regular query search on only posts in category 3 by using a hidden input. The value for the “cat” variable can actually be comma separated to include multiple categories, such as “3,5,7”. We can display this form only when in the dog section by putting an “if” in the “searchform.php”, or possibly just the “sidebar.php” (that wouldn’t appear on the “No results” page though), that checks the page, post category, or search query category ($_GET['cat'] == 3):

if(
	is_page('adopt-a-dog') ||
	is_page('adoption-process') ||
	is_page('mended-mutts') ||
	in_category('adoptable-dogs') ||
	$_GET['cat'] == "3"
): // display dog search form
else: // display normal search form
endif;

As the search is sent as a GET request, URLs can also be crafted with the appropriate variables so that you can have a link to a page with a certain result set. This link shows all posts from the current year in category 3:

http://repMyURL.com/?cat=3&year=<?php echo date('Y');?>

As all but the “s” parameter seem to be apendable to permalinks and have their affects, the above could become:

http://repMyRL.com/category/adoptable-dogs/?year=<?php echo date('Y');?>

when that permalink structure is used and category 3 is called “adoptable-dogs”.

Since we store much of the dog data in the custom fields, we need to be able to search those. By default, these parameters of “query_posts” are available, as currently found on line 29 of classes.php:

array('m', 'p', 'posts', 'w', 'cat', 'withcomments', 'withoutcomments',
's', 'search', 'exact', 'sentence', 'debug', 'calendar', 'page', 
'paged', 'more', 'tb', 'pb', 'author', 'order', 'orderby', 'year',
'monthnum', 'day', 'hour', 'minute', 'second', 'name', 
'category_name', 'tag', 'feed', 'author_name', 'static',
'pagename', 'page_id', 'error', 'comments_popup',
'attachment', 'attachment_id', 'subpost', 'subpost_id', 
'preview', 'robots', 'taxonomy', 'term', 'cpage')

That gives a lot to work with, but the important meta parameters (meta_key, meta_value, meta_compare) that we’d need to search through custom fields are not available. They can easily be added, though, by adding the following to “functions.php” or a plugin:

$wp->add_query_var('meta_key');
$wp->add_query_var('meta_value');
$wp->add_query_var('meta_compare');

This can, of course, be used to add any of the parameters not normally available.

On the canine site, we want links for different age groups and other attributes stored in custom fields. We can use the meta parameters in URLs for this. For example, puppies can be found like:

http://repMyURL.com/category/adoptable-dogs/?meta_key=age&meta_value=Puppy

WordPress stores custom fields as rows rather than columns. This makes it easy to add any number of custom fields to any posts or pages without affecting the others. Unfortunately, it makes it hard (and inefficient) to search using them. With the method above, we can only search with one field at a time. For the canine site, we will probably need multiple fields at once to be searchable. This could allow an advanced search page with multiple parameters, but it would also allow us to show, for instance, only adoptable dogs in normal searches.

There is a plugin called WP Custom Fields Search that I will have to check out. It allows searching by multiple parameters, but I’m not sure if it allows multiple custom field parameters. If not and I determine this functionality is really needed, I may have to craft my own complex search function with ad-hoc custom queries that join an instance of the table(s) of meta-data for each query parameter. This would be complex, messy, and inefficient. Or I could store the dogs in Pods CMS and figure out searching with that.

About these ads

6 thoughts on “Canine: WordPress Custom Searches

  1. hi
    i’m so glad that i found this website. that posting was so cool. thanks again i saved this site.
    are you going to write similar posts?

  2. Hey, cool post – I’m trying to create a set of custom searches as links on the home page above, but the search results page appears not to be searching within my custom fields, especially one called 326_dtg, which contains date information.

    Do you know how I can ensure that the default search function will search within our custom fields? I tried adding

    $wp->add_query_var(‘meta_key’);
    $wp->add_query_var(‘meta_value’);
    $wp->add_query_var(‘meta_compare’);

    to functions.php, but no joy… I’m sure there must be something I’m missing about that. Can you help?

    • Sorry for the delayed response, I was on vacation for a bit.

      It’s been a little while since I worked with the above method: I ended up using Pods for the project mentioned above, and the project ended up getting canceled anyways. I’m not sure why it wouldn’t be working for you. Does it work with the form and named fields? Do you have your permalinks set up unusually? Keep in mind that dates in custom fields will be stored as strings, so normal date comparisons won’t work. If you have fairly complex data needs, you could try Pods. It takes a bit of figuring out, but can be quite powerful.

  3. Hi tobymackenzie,

    Thank you so much.I am a beginner in wordpress.This post gave me enough knowledge for multiple search formats.Thanks again.

  4. @Toby: Do you know if this will work with the latest version of WordPress 3? All the fixes for this issue that I’ve tried haven’t worked so far (due to outdated wordpress codes form older versions of WP). Rather than trying first, I figured I’d drop you a line to see if you think it will work on WP3. Please advise. :)

    • I haven’t used this method on any new sites and the site I originally did this for was never put into production. I still have the site in test though. I upgraded it to 3 and it still is working, I haven’t needed to change anything. It should work for you, good luck.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s