Building a Product Filter with WooCommerce and FacetWP
Awhile back I built a WooCommerce store for a boutique children’s clothing store. One of the requirements I was given was that there needed to be product filters to allow visitors to quickly narrow down the product offerings based on multiple criteria: size, color, etc. I tried a couple of free plugins but none of them quite fit the bill. My requirements boiled down to the following:
- AJAX support (i.e. the entire page does not refresh when a filter is selected).
- Filters should be hidden until needed.
- Ability to filter by WooCommerce category and variations.
This last requirement was the one I found to be the hardest to deal with. Lots of filter plugins can filter on product attributes, but this wasn’t useful for me because this particular shop didn’t setup products to use all attribute combinations. For example, the products all have 3 attributes: size, color, and style. But we don’t create a variation for each possible combination of these attributes. So a particular design might have the color white available in size 2 and 4, but black may only be available in size 2. Filtering on attributes alone will not capture this information and causes the filter results to display products that don’t really exist.
This is why I settled on FacetWP for the filter. It’s by far the most expensive WooCommerce filter plugin out there ($99 for a one year license), but it was also the only one that met my filter needs. Combined with another free plugin, I was able to create a WooCommerce filter solution the met all of my client’s needs. Below I will walk you through how I did it.
1. Install Required Plugins
The get started, install the required plugins. At a minimum you’ll need FacetWP, which is a paid plugin available only on their website, as well as a free plugin called MoJo Slider Panel. Each of these plugins serves a distinct purpose. FacetWP provides the core filtering functionality, while MoJo Slider Panel provides a nice hidden widget area that slides out to reveal the filter controls.
Note that the MoJo Slider Panel plugin is optional. You could just as easily place the filter controls (i.e. the Facets) into a standard WordPress sidebar or other widget area. However, for this project I preferred having the WooCommerce products display in a full width section instead of sharing screen real estate with a sidebar. The MoJo Slider Panel provides 2 sliding panels, one on each side of the screen, that can hold any widgets. The panels tuck away nice and cleanly when not needed, and easily appear when the user wants them.
If you don’t have access to cPanel or some other file editing tool for your server, I also recommend installing a file management and editing plugin. Later on you’ll need to copy a PHP file from the WooCommerce plugin directory into your child theme. One way or another you’ll need the ability to copy, create, and edit files on your server.
2. Update Product Archive Template
To get WooCommerce and FacetWP to play nicely, you have to edit the product archive template that comes with WooCommerce to include a new HTML div element that FacetWP can use to find the products on the page. Without this step, your filter will not be very useful. I used cPanel’s file management tool, but as mentioned earlier you can also get by with a file management plugin. All you need to do is copy the following file:
to your child theme:
Note: If you’re using a WordPress file management plugin, you may not be able to copy/paste files. Instead, open the WooCommerce template file, copy the contents, and then create a new file in the child theme and paste in the contents from the template.
Leave the file name exactly the same. Once it’s been copied into your child theme, open the new file and paste the contents of the file below into it (replace all existing content in the file with this one):
For reference, the only thing I have changed in this file is adding two new div elements right before the have_posts() line. The first one is used to anchor the MoJo Flyout Panel on the screen, and the second is used by FacetWP so it can dynamically determine which products are being displayed at any given time. Even if you do not intend to use the MoJo panel to display the filter controls, leaving the extra div element in your code will not cause any harm. For completeness, the other change is adding the closing tags for the new elements after the endif statement. Note that I have placed HTML comments with the word Elvtn to help identify what I changed.
This part may seem confusing, especially for those who are not familiar with navigating the WordPress directory structure or working with PHP. But without this step the whole thing falls apart. FacetWP must have this HTML markup in order to function with WooCommerce. And remember that anytime WooCommerce updates this template (which should be very infrequently, but nonetheless possible) you will need to update the copy of the in your child theme directory by copying the latest version from the WooCommerce plugin directory and re-applying the 2 changes I noted above.
3. Configure WooCommerce and FacetWP
Once you are finished updating the product archive template, the hard work is done. The remaining configuration is all done through normal WordPress admin screen. The first step is to create the facets, which are the controls that visitors will use to actually filter products. Facets can be tied to any number of taxonomies: category, attribute, tag, etc. In my case, I need to filter on 4 things:
The category is simply the WooCommerce product category, and the other 3 are custom attributes we defined. Obviously your shop may have different attributes, but the instructions should make it clear how to set them up. First, we’ll do the category facet since it’s the easiest. Facets are configured by going to Settings > FacetWP on your admin screen. Click the Add New button and configure it just like the screen below:
A couple of notes. First, the facet name is “categories” which we’ll need to remember later to display the filter in our widget area. Second, the Data Source is product categories. I’ve also set the count and soft limit fields to 10. These should be at least as big as the number of categories you have in your shop, or the filter control will not display all categories. Once you’re done, make sure you save the facet.
Now you’re ready to configure the facets for product attributes. Again, click the Add New button and this time for the Data Source you’ll need to find the specific attribute you want to use. Also remember to set the count and soft limit fields to be at least as big as the number of attribute values you have configured in WooCommerce. For example, if the attribute is size and you offer 8 sizes, make sure these fields are both at least 8. In fact I like to set to a little bit higher to allow room for future values. Also remember to give them meaningful names so it’s easy to create the filter widgets later.
Here is an example of creating a WooCommerce FacetWP filter for an attribute:
Finish creating all the facets you need for your shop. When you’re done saving all of them, you’ll need to click the Settings button on the FacetWP screen, and then WooCommerce. On this screen, make sure you set the Support product variations dropdown to Yes. This is the key setting that allows FacetWP to filter your variable products, and not just display products that have an attribute. On this screen you can also decided if you want FacetWP to display out of stock products in filter results.
When all of your facets have been created and settings have been updated, you’ll want to click the Re-index button on the main FacetWP screen. This will force FacetWP to rebuild its internal data structures it uses for filtering.
That’s it for FacetWP setup, and now you can move on to WooCommerce. The only setting you have to care about is making sure your shop page is configured, which it likely already is. FacetWP does not work with WooCommerce short codes, so you must have a main shop page set. Other than that, there’s nothing to really tweak for WooCommerce to make it work with FacetWP.
4. Configure FacetWP Widgets and MoJo Slide Panel
The MoJo Slide Panel plugin is optional. I chose to use it so that the filter controls can be hidden by users that don’t want it, but you can certainly use normal sidebar widget areas if you like. Defining the facet widgets is the same regardless, the only thing that’s different is the bit about MoJo settings. If you don’t intend to use the MoJo plugin, just create the widgets and skip over the part.
First we’ll create the FacetWP widgets. If you’re planning to use the MoJo plugin, create them in the flyout panel of your choice (left or tight). Otherwise, just create them in whichever widget area you want. Either way you’ll want to create a text widget for each facet you created in the previous step, and each text widget will have a single short code in it:
Notice the facet value is set to the name of the facet we want to display there. When you’re all done your widget area will look something like this:
For those of you using the MoJo widget area, proceed to the plugin settings by going to Settings > MoJo Slide Panel. The screen shot below shows the settings I used, but in general here is what I recommend:
- Show Panel By Default: Uncheck, otherwise when the page loads the panel will be displayed which may catch some visitors off guard and cover some of your products.
- Target element: This needs to match the name we used earlier when updating the product archive template, which means it should be “#mojo-slider”.
- Panel z-index: The flyout panel needs to appear in front of all other elements on the page or the user won’t be able to see it, so set this value to something very high. I used 99999, which should work for most sites.
Those are the settings I changed, but you can also change the background color, width, and icons used for the show and hide buttons. Putting it all together here is a screen shot showing what the options look like on my site:
Pulling It All Together
I wanted to show a preview of what all the hard work looks like. The video below shows the final WooCommerce shop page for the site I built this on, including the MoJo flyout panel. Notice the panel is activated with a discrete icon on the left side of the products. Once open, the user has 4 areas to filter: category, style, size, and color. The product list is dynamically updated each time a checkbox is selected, eliminating the products which no longer meet all filter selections. FacetWP also handles updating the filter text in the flyout panel to indicate the number of products that match each filter.
If you want to actually see it in action and play with it, the website is https://jackandnicole.com.
Alternative WooCommerce Filter Plugins
One of the great (and sometimes maddening) aspects of working with WordPress is that there are usually multiple ways of accomplishing the same thing. The solution I cam up with here is by no means the only way of doing filtering with WooCommerce, and I freely admit it may not even be the best. But it works well for my use case and was easy to setup. I thought it might be useful to point you to some additional plugins I tried to use, in case you find them more suitable for your project than I did.
WooCommerce Product Filter
Available on CodeCanyon.
This plugin was my next choice, as it supports a lot of different ways for filtering. One nice thing is that you can filter with WooCommerce short codes, so you don’t have to use the shop page for placing filters. It also supports AJAX filtering, is highly configurable, and even has metrics so you can see how your visitors are actually using the filter. The one thing I really like about this plugin is that it has a built-in collapsible filter panel, so no need to include an extra plugin to achieve that functionality.
Unfortunately it doesn’t support variable product filtering, so it didn’t quite my needs. The options panel is also a little overloaded with choices, so it was a little overwhelming at first to try and decipher what every option meant.
WOOF Product Filter
Available on CodeCanyon.
This is another paid plugin and has a lot of similar features to the other CodeCanyon plugin above. It supports AJAX filtering, filtering on non-shop pages, and also provides filter metrics. At the time I tried this plugin, only the free version was available to me and it didn’t support filtering outside the shop page. Otherwise it looks like a solid competitor to the other CodeCanyon plugin, at a similar price.