How to implement Faceted Search in WordPress

facet search in wordpress

Introduction

FacetWP plugin can be used to implement faceted search in a WordPress website. It can be utilized along with the Address Geocode plugin for proximity search, WPCore search, or Relavanssi plugin to search by name, conditional logic plugin to set up conditions for facets and WP hooks, or other options for custom query implementation. Read further to know about faceted search and different plugins that can help in implementing different functionalities for faceted search in detail.

The Use Case

We recently implemented a faceted search for an insurance client of ours: Burns and Wilcox. You can see the implementation here: https://www.burnsandwilcox.com/our-experts/expert-search

facetted search in wordpress use cases

You will notice a few key aspects of this faceted search:

  • It brings up a list of experts at Burns and Wilcox
  • This list is filtered by proximity to your location (that is automatically detected). If the location is removed, then we were expected to show national results.
  • You can choose the results from a search radius (50 miles, 100 miles, 250 miles etc)
  • You can filter by two different facets : Practice Area and Specialty
  • You can narrow your search results by typing in the name of an expert
  • The client needed to sort these results based on the seniority of the expert
  • Finally, there was a lot of conditional logic around when you could show search results vs. not.

Clearly, a complex facet to implement!

Introduction to FacetWP

FacetWP is the premier WordPress plugin for implementing faceted search. A few key highlights of the product are shown below:

facetWP features

Reference: www.facetwp.com

Proximity search

proximity search in facetWP

FacetWP’s “proximity facet” lets you find results near a specified location. The process to achieve this is as follows:

First, we need to enable “latitude/longitude” coordinates for the Expert’s custom post type. For eg. we need to be able to say that Expert A is located at so-so latitude/longitude.  To achieve this, we used a plugin called Address geocoder. Then we mapped the location datasource in FacetWP to this field.

location search in facetwp

Second, when a user comes to this page, we need to determine his lat/long. After a user gives us permission to track his location, we make a call to the Google API that returns his lat/long.

location notification in browser
geolocation code for google maps

The lat/long information is then stored in the browser cookie which is picked up by FacetWP.

geo location lat long codes

This information is used by FacetWP to provide features to limit the search to a user-defined radius (such as 50 miles, 100 miles etc)

facetWP geo location settings

The actual query for pulling up the list of experts within a 50/100 mile radius of the user’s location is executed within the “templates” provided by FacetWP.

facetwp wordpress plugin templates

Search by Name

facetted search by name in wordpress

“Search by name” requires robust search capabilities that are not offered in FacetWP. It integrates with two options: WPCore Search and Relevanssi.  Using WP core search limitsyou to the post title, excerpt, and body. However, if you need more flexibility, you can use an advanced plugin like Relevanssi. This lets you search other advanced custom post data such as custom fields, taxonomy terms, PDF contents, etc.

After you have installed the plugin, additional options will show up in the search settings of FacetWP as shown below:

facetWP search bar settings in WordPress

So when a user searches for say “John”, the following sequence is executed:

  • The search term “John” is passed by FacetWP to Relevanssi
  • Relevanssi returns the relevant results for “John” based on its search index
  • These results are filtered by the Facet, to show only the results that satisfy the proximity criteria (Eg. Show all Johns within a 50 mile radius)

Facet Dimensions

FacetWP Dimensions

FacetWP lets you create “facets” as shown below:

Facet creation in WordPress

As you can see, you can do a few main things:

  • Decide which aspect you want to filter the resultset on. In this example, you are filtering by the “specialty” of the expert. (see example below)
  • There are different types of facets: checkbox, dropdown, date range etc (see image below)
different types of facet categories
  • You also have a few other options such as the number of values you want to show in the facet, what you want to happen when a user clicks on a value, how you want to sort the list of values etc
additional facet categories

Custom Query Implementation

screen with user profiles

“Custom Query” is an advanced feature that is used when the query is more complex than can be handled within FacetWP. For example, in the scenario above, the client had complex rules around which person should be shown first, based on their seniority, physical location and role. This couldn’t be handled within the basic query capabilities of FacetWP. So, we had to go with custom queries.

First Option : WP Hooks

FacetWP hooks can be added to functions.php theme file but we wouldn’t recommend it because the site will completely crash should there be errors.  So we downloaded  the Custom Hooks Plugin and activated it in the wp-admin. This allowed us to add relevant code in custom-hooks.php. The advantage of this approach is that WordPress will simply disable the plugin should it trigger a PHP fatal error, instead of the whole site coming down.

ftp page screen

Now we can separate the custom query from facetwp admin by placing it anywhere in the theme php templates and add a facetwp argument. This would then enable FacetWP to detect the query.

Second Option: Custom WP_Query

If you’re trying to show facets on a WP page template (with a custom WP_Query), FacetWP won’t be able to auto-detect the query. You can nudge FacetWP into detecting the query by adding the query argument as shown below:

code snippet

As an example, we wrote a custom query in a separate template instead of the FacetWP admin. This query will get detected by the Facetwp by setting the argument “facetwp” to true.

                        $emp_args = [    ‘posts_per_page’ => 1,
                                                       ‘post_type’ => ’employees’,
                                                       ‘facetwp’ => true,
                                                       ‘post__in’ => $empid,
                                                       ‘orderby’ => ‘date’,
                                                     ‘  meta_query’ => [   [
                                                              ‘key’ => ‘office_code’,
                                                              ‘value’ => ‘IL01’,
                                                              ‘compare’ => ‘LIKE’,
                                                       ]  ],
                                                       ‘no_found_rows’ => true,
                                                      ‘post_status’ => ‘publish’    ];                                                

Third Option: facetwp_query_args

This filter lets you override the Query Arguments field from FacetWP templates. The Query arguments array (used by WP_Query) tells WP which posts to retrieve from the database.

As an example, in this hook we have a query argument for filtering the employees with the ‘practice_area’ taxonomy attached to it. Also we added conditional logic for restricting the query arguments for a particular template named ‘experts_template’.

                         add_filter(‘facetwp_query_args’, function ($query_args, $class){
                        if (‘experts_template’ == $class->ajax_params[‘template’]) {
                        $query_args[‘tax_query’] = [
                        [
                        ‘taxonomy’ => ‘practice_area’,
                        ‘operator’ => ‘EXISTS’,
                        ]
                        ];
                        }
                        return $query_args;
                        }, 10, 2);

Final Option: facetwp_pre_filtered_post_ids

In this option, we can choose the initial bucket of post IDs before any filtering is applied. This is especially useful due to the WP limitation that prevents “post__in” and “post__not_in” from being used simultaneously.

For example, in this following hook we are preventing a particular post from appearing in the query result using the post ID.

                     add_filter( ‘facetwp_pre_filtered_post_ids’, function( $post_ids, $class ) {
                     if ( false !== ( $key = array_search( 42, $post_ids ) ) ) {
                     unset( $post_ids[ $key ] );
                     }
                     return $post_ids;
                     }, 10, 2 );

A very useful Add-on

There is a very useful FacetWP plugin called Conditional Logic. This plugin can set up many different conditions related to facet and facet template, and can be a great replacement for tons of custom js that might otherwise be needed.

For eg. the client requirements were as follows:

search query sample for facetWP wordpress plugin

When the user first comes to the page, there would be no location selected. When both name + location are empty, we were required to show some static text (as shown above).

If the user typed in the “Search by Name” field, then we had to show results.

Similarly, if the user selected his location, then we were required to show the results. At this stage, however, if you “cleared location”, then you were required to hide the results again (shown below)

facet search filters
additional facet search filters

As you can see, there was a lot of conditional logic around how the facets should behave. Implementing this manually would have required a ton of custom javascript. With the Conditional Logic plugin, we were able to simply define the rules (see below) and the plugin executed all the logic.

facet conditions page

Summary

In this post, we discussed how to implement faceted search while building a WordPress site. Specifically, we covered some key features of the FacetWP plugin and discussed how to implement advanced features such as building custom queries and implementing conditional logic.

If you enjoyed this article, we've also got a great article on setting up a multilingual site on WordPress, which you may enjoy.

No items found.

Related Insights

Building a Design System in Elementor

Processwire is UI agnostic with no fancy visual builders and has basic UIKit components. Click here to know the approaches required to switch from Processwire to WordPress.

Anirudh Mahant

WordPress

Jetpack for Wordpress

We review the popular Jetpack plugin for WordPress. We evaluate the pros and cons and let you decide if this plugin works for you.

Saichand

WordPress

Introduction to Component Design for Websites

Component-based design thinking is essential to ensure coherence, consistency and productivity when building large websites. We discuss what typical website components look like and how they are organized.

Anirudh Mahant

WordPress

Subscribe to our newsletter