Rumblings from the keyboard of Pete Eveleigh,
a web designer and developer based in Gloucester, UK

Searching across multiple categories with ExpressionEngine

Posted: July 29th, 2011 | Author: | Filed under: How to, Web Design | | 4 Comments »

I recently put a new ExpressionEngine site live which featured a search facility that returned results based on multiple category selections. To do this without using a third-party add-on such as Super Search I had to create a little work-around. To be honest, I didn’t think much of this as it seemed quite straightforward but a number of people have asked me how I did it so I thought I would share the information here – mainly because I’m likely to forget an need to do it again at some point.

The premise is thus: We have a number of “products” that are assigned categories. Each product can have more than one category.

We want to be able to search for products based on these categories and return results (for the sake of this demo) that exist in multiple categories.

Our search box might look something like this:

search box

Each drop-down in the search represents one of our categories and is set to return the category id when the form is submitted.

Here is our form’s HTML with EE tags inserted…
<form method="post" action="/search-results/">
<select id="roomtypesel" name="cat[]">
<option value="">Room type</option>
{exp:channel:categories channel="products" category_group="1" style="linear"}
<option value="{category_id}">{category_name}</option>
{/exp:channel:categories}
</select>
<select id="flooringtype" name="cat[]">
<option value="">Flooring type</option>
{exp:channel:categories channel="products" category_group="2" style="linear"}
<option value="{category_id}">{category_name}</option>
{/exp:channel:categories}
</select>
<select id="colourtype" name="cat[]">
<option value="">Colour type</option>
{exp:channel:categories channel="products" category_group="3" style="linear"}
<option value="{category_id}">{category_name}</option>
{/exp:channel:categories}
</select>
<input type="submit" value="Find products" />
</form>

So what we have there are a number of select boxes generated by looping through our chosen category groups and outputting each category as an option.

Note that each select has the same name attribute and we have called that ‘cat[]‘.

When the form is submitted the data from it is POSTed to our ‘search-results’ template and by giving each select the same name attribute, and using the ‘[]‘ we pass the category id of each selection along as values within a single array.

On the search-results template we must enable PHP parsing. This allows us to retrieve the values from the POSTed array and do something with them.

The way in which I do the actual search is to grab the values from the array, combine them into a string and then feed that string into a regular ExpressionEngine channels tag. Because we want to find things that exist in ALL the categories we are interested in we join the category IDs together with a ‘&’.

So within our search-results page we add the following code (including a bit of mild sanitation to ensure we are only getting id numbers)

<?php
// Grab the categories selected from the $_POST
// join them with an ampersand - we are searching for AND matches
$cats = "";
foreach($_POST['cat'] as $cat){
// check we are working with a number
if(is_numeric($cat)){
$cats .= $cat."&";
}
}
// strip the last & off the category string
$cats = substr($cats,0,-1);
?>

Then, within our template we can use the ExpressionEngine Channels tag and feed our string into the category parameter to get the entries that match…

{exp:channel:entries channel="products" dynamic="on" category="<?php echo($cats);?>" orderby="price" sort="asc"}

And that’s it!


4 Comments on “Searching across multiple categories with ExpressionEngine”

  1. 1 Ian said at 10:36 pm on August 25th, 2011:

    This is exactly what I needed to develop a browsing system for real estate listings. Thanks a lot! :)

  2. 2 John Derrick said at 2:35 pm on July 25th, 2012:

    This was an excellent resource and saved me a ton of time in EE. I kept trying to use the Advanced Search module, but this worked like a charm. Thank you for posting this.

  3. 3 Bob Foster said at 12:14 am on November 10th, 2012:

    Thanks much for this solution. Was exactly what I was looking for. Any way to put this into an Exp Eng add-on, extension, etc. instead of having php code in the template?

    - Bob.

  4. 4 Philip Zaengle said at 5:32 am on November 19th, 2012:

    If your looking for this without using php in templates take a look at Low Search, it adds this functionality along with a ton of other good stuff.

    http://gotolow.com/addons/low-search


Leave a Reply