Advanced search in WordPress themes

by admin on November 9, 2010 · 17 comments

in Settings

For some time now, I’ve been meaning to build an advanced search in WordPress. So now that all the functionality is available in core functions like query_posts, it looks like it’s just a matter of piecing it all together. Easy, right? Previously, I had been using plugins like Multiple Category Selection Widget and Query Multiple Taxonomies, but I either found bugs with new 3.0 features or the widget-style operation too restricting for my purposes. I like widgets, but I wanted my advanced search to appear on its own page.

So here is a quick run through of how you can add an advanced search page to your WordPress theme. For simplicity sake this tutorial will demonstrate how to use multiple categories at once. Truly advanced search would also combine keywords, sorting, filtering and more advanced user input. We’ll save those options for a later day.

Create a page template file in your theme

I really like using page template files, it makes it easier to work in ‘the loop’ and you have more space to build interfaces. In your theme folder create a file called template-advanced-search.php. A WordPress template file only needs the following code to make itself available to pages in wp-admin.

<?php
/*
Template Name: Advanced Search
*/
?>

Create a new page and attach the template file

Now you just need to attach the page template to a new page in wp-admin. Create a new page called ‘Advanced search’. If you created the page correctly you’ll see a reference to it in the page options. Select your template and publish the page.

Page Template Animation

Page Template Animation

Build form with wp_dropdown_categories

wp_dropdown_categories is a very useful core function that we can quickly use to build our advanced search form. In this example, we’ll be using this function combined with parent and child category groups. Creating parent and child category groups is easy. Go play around in the admin section (wp-admin/edit-tags.php?taxonomy=category) and work it out. Essentially, you want to create the following structure:

  • Category 1
    • Child 1
    • Child 2
    • Child 3

Create 3 separate parent child groups.

Here is an example of the code should look now in template-advanced-search.php.

<?php
/*
Template Name: Advanced Search
*/
?>
<h2><a href="<?php the_permalink(); ?>" title="<?php the_title(); ?>"><?php the_title(); ?></a></h2>
<form action="<?php bloginfo('url'); ?>" method="get">
<h3>Category 1</h3>
<div><?php wp_dropdown_categories('child_of=1&show_option_none=Not selected...&hide_empty=1&name=cat[one]'); ?></div>
<h3>Category 2</h3>
<div><?php wp_dropdown_categories('child_of=2&show_option_none=Not selected...&hide_empty=1&name=cat[two]'); ?></div>
<h3>Category 3</h3>
<div><?php wp_dropdown_categories('child_of=3&show_option_none=Not selected...&hide_empty=1&name=cat[three]'); ?></div>
<br />
<div><input class="button" type="submit" name="submit" value="Advanced Search" /></div>
</form>

Now to get the above example to work properly with your categories, you need to edit the code above so that each of the <code>child_of=X</code> references actually refer to real parent category IDs from your WordPress install. So, change the numbers 1, 2 and 3 to the parent category IDs you are using.

Control results with query_post in index.php

Now you just need some code to catch the get parameters from the URL and send that to the query_post function. query_posts will modify the loop to only show the posts that match you’re combination of categories. The following is very simplified code for index.php. If you’re testing this on an existing theme back-up your existing index.php before over-writing.

<?php
if ($_GET['submit'] == 'Advanced Search') {
	$pladvsearchcatids = Array ();
	$pladvsearchcatnames = Array ();
	foreach ($_GET['cat'] as &$pladvsearchcatvalue) {
		if ( $pladvsearchcatvalue != "-1" ) {
			array_push($pladvsearchcatids, $pladvsearchcatvalue);
		}
	}
}
global $wp_query;
query_posts( array_merge( $wp_query->query, array( 'category__and' => $pladvsearchcatids )));
if (have_posts()) :
   while (have_posts()) :
      the_post();
      the_content();
   endwhile;
endif;
?>

That’s it, now you should have the basics of advanced multi-category search working.

If you have any questions, please use the comments below…

Related posts:

  1. WordPress 3 template hierarchy
  2. WordPress themes
  3. Importing CSVs into Bento
  4. NetInsight: find and replace custom session ids from URLs
  5. SCP SSH custom ports

{ 17 comments… read them below or add one }

1 Guest December 3, 2010 at 5:49 pm

Hi,

How does one get results to show up properly? i.e. regardless of item searched, it just displays the main blog page.

Also is there a way to use category names instead of ID#s?

Thank you.

Reply

2 admin December 4, 2010 at 6:35 am

Did you edit your index.php file to contain the code display in the last step above?

The child_of variable in wp_dropdown_categories only accepts integers. So, no, I don’t see a way to use category names instead of IDs.

Reply

3 agabu January 19, 2011 at 7:44 pm

Thanks a lot for the tutorial. It was exactly the intro I needed to start understanding the main idea of custom search working.
One little note, I added the categories and subcategories but didn’t assign any posts to them at first, so I initially got stuck but after then your tutorial turned out to be really helpful. Thank you.

Reply

4 admin January 19, 2011 at 8:49 pm

agabu, thanks for the comment! That’s exactly why I wrote it.

Reply

5 baalstorm July 4, 2011 at 6:44 pm

HI! i was using this great tip and it worked like a charm, but now – don’t know why – i get this :
Warning: urldecode() expects parameter 1 to be string, array given in /web/htdocs/www.archivioflaviobeninati.com/home/archivio/wp-includes/query.php on line 1702

do you have any idea what’s going on? :/
thanks a lot

Reply

6 baalstorm July 4, 2011 at 6:52 pm

looks like the problem starts when i put those name=cat[one], name=cat[two], name=cat[three] in… i used to change them to the id’s of the categories i wanted to show in the dropdown list..

Reply

7 admin July 13, 2011 at 7:29 am

Weird. Did you manage to fix it?

Reply

8 daniele November 25, 2011 at 8:26 am

HI! I used this tutorial but i have an error like baalstrom, this :
Warning: urldecode() expects parameter 1 to be string, array given in /web/htdocs/www.archivioflaviobeninati.com/home/archivio/wp-includes/query.php on line 1722

Someone can help me?

Reply

9 admin December 9, 2011 at 10:20 pm

I think my tutorial fails when you use integer values. Are you using post IDs at all?

Reply

10 seba July 12, 2011 at 9:13 pm

just wanted to thank you man, I’ve been looking for this tutorial for such a long time!!

Reply

11 admin July 13, 2011 at 7:26 am

You’re very welcome. I found it hard to find examples like this online when I was researching it.

Reply

12 Jason November 18, 2011 at 6:30 pm

Great tutorial! Question… is there a way to make this spit out just a single random result? For example, if the search generates, say, 10 matches, it will only display one at random. Any help would be greatly appreciated. Thanks!

Reply

13 admin November 24, 2011 at 6:45 am

I’m sure that’s possible, but why would you want to do that? The idea behind this advanced search was to increase accuracy of a user’s search.

Reply

14 Stefano November 29, 2011 at 2:52 pm

Hi guys,
following this tutorial I made an advanced search page for a real estate site. It works like a charm but now, after upgrade wordpress to 3.2.1 I have a problem.
When someone click on search button wordpress does the work but he give me that error:

Warning: urldecode() expects parameter 1 to be string, array given in /home/hosting/p/provestefanino/www/wp-includes/query.php on line 1722

I’m working hard to solve it but I’m not a programmer and I don’t know how I can fix it.

it’s the first time I have a problem after an upgrade.
Can someone show me how to solve it?

Reply

15 Stefano November 29, 2011 at 3:13 pm

.. if you want to look the error is here

http://immobiliareballetto(dot)it

Reply

16 admin December 9, 2011 at 10:21 pm

My tutorial fails when you use integer values. Are you using post IDs?

Reply

17 Stefano November 29, 2011 at 7:22 pm

ok..

i’ve solved the problem downgrading to wordpress 3.0.4 ..

now it works again but i’m still curious..

Reply

Leave a Comment

You can use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Previous post:

Next post: