This page is meant to give a comprehensive overview in one place of all aspects and intricacies of using FacetWP with taxonomies.

Taxonomies, and specifically “hierarchical” taxonomies are one of the most important ways to structure and order content in WordPress. This makes them an excellent candidate to filter content by, with facets.

FacetWP works very well with (hierarchical) taxonomies. Any supported listing template can be filtered with facets that have a (hierarchical) taxonomy as data source.

And, any facet type can be placed on a taxonomy term archive page. Also facets that have the same (hierarchical) taxonomy as data source.

What is a taxonomy?

First things first: what is a taxonomy? A taxonomy is a WordPress construct that stores and orders “terms”.

Taxonomies can be “attached” to one or more built-in or custom post types. In posts of these post types, the user will see the option to check one or more terms for each taxonomy that is attached to that post type.

What is a “hierarchical” taxonomy?

A hierarchical taxonomy with five levels
A hierarchical taxonomy with five levels.

Any taxonomy can be defined (registered) as being “non-hierarchical” ( or “flat”) or “hierarchical”.

In a non-hierarchical/flat taxonomy, there are no levels: all terms are at the same level. In a hierarchical taxonomy, the terms are structured in a tree-like hierarchy: one or more (nested) levels of parent and child terms. The example on the right shows a “location” taxonomy with five nested levels of terms.

WordPress has several built-in taxonomies. Most used is the category taxonomy, which is a hierarchical taxonomy. When you add a new category, you can set its parent category, which creates a hierarchical relationship between these categories.

The built-in post_tag taxonomy lets you select tags in posts. This is a non-hierarchical or flat taxonomy: tags never have a parent or child tag. It is possible to make tags hierarchical, but if you need this, it would be better to create a custom taxonomy instead.

Besidescategory and post_tag, WordPress has a few more built-in taxonomies: post_format, nav_menu, and link_category. But these generally are not used to structure and filter your content.

How to create a custom (hierarchical) taxonomy

If WP’s built-in category (hierarchical) and post_tag(non-hierarchical) taxonomies are not enough to structure (and filter) your content, you can add your own custom taxonomies.

As many plugins and themes do, you can programmatically add taxonomies with WP’s register_taxonomy() function. For example, WooCommerce adds the product_cat taxonomy for product categories.

Or you can use a plugin like Advanced Custom Fields, Pods or Custom Post Type UI to create (“register”) your own custom taxonomies.

The 'Hierarchical' setting in Advanced Custom Fields' 'Edit Taxonomy' settings.
The “Hierarchical” setting in Advanced Custom Fields’ “Edit Taxonomy” settings.

To be “hierarchical”, (custom) taxonomies need to have the hierarchical argument of register_taxonomy() set to true. If you use the above-mentioned plugins, this is a setting you can enable, as shown on the right for Advanced Custom Fields.

How to make an existing taxonomy hierarchical

To be hierarchical, existing (custom) taxonomies would need to have the hierarchical argument set to true when they are created with WP’s register_taxonomy() function.

If you created the custom taxonomy yourself, using register_taxonomy(), just set the hierarchical argument of register_taxonomy() to true. If you used a plugin like Advanced Custom Fields, Pods or Custom Post Type UI), this is a setting you can enable.

However, if you don’t have access to the register_taxonomy() arguments, for example because the taxonomy was registered in a theme or plugin, you can also set the hierarchical argument to true with the register_taxonomy_args filter, like this:

How to use custom PHP code?

PHP code can be added to your (child) theme's functions.php file. Alternatively, you can use the Custom Hooks add-on, or a code snippets plugin. More info

add_filter( 'register_taxonomy_args', function($args, $taxonomy) { if ( $taxonomy === 'my_taxonomy_name' ) { // Replace 'my_taxonomy_name' with the name of your taxonomy $args['hierarchical'] = true; } return $args; }, 10, 2 );

For some taxonomies, you may need to use specific hooks, like for WooCommerce product attributes and product tags, which are both taxonomies:

Make product attributes or product tags hierarchical

WooCommerce product attributes (which are custom taxonomies) are not hierarchical by default. If you want them to be, add the following code to your (child) theme’s functions.php. Make sure to replace color with the name (the slug) of your attribute, and keep pa_ before it:

How to use custom PHP code?

PHP code can be added to your (child) theme's functions.php file. Alternatively, you can use the Custom Hooks add-on, or a code snippets plugin. More info

// Make Woo product attributes hierarchical. // Replace "color" with the name (slug) of your attribute. Keep "pa_" before it. add_filter('woocommerce_taxonomy_args_pa_color', function( $args ) { $args['hierarchical'] = true; return $args; });

Now you can use this attribute in a hierarchical facet and show parent and child terms/choices.

The same can be done with product tags:

How to use custom PHP code?

PHP code can be added to your (child) theme's functions.php file. Alternatively, you can use the Custom Hooks add-on, or a code snippets plugin. More info

// Make Woo product tags hierarchical. add_filter('woocommerce_taxonomy_args_product_tag', function( $args ) { $args['hierarchical'] = true; return $args; });

Use a hierarchical taxonomy as facet data source

Most facet types can have a (custom) taxonomy set as their data source. The selected taxonomy can be a non-hierarchical or a hierarchical taxonomy.

Some facet types have a “Hierarchical” setting, which will make the facet visually display the hierarchical levels of the terms.

Display only children of a parent with term ID 46.
Display only children of a parent with term ID 46.

The Checkboxes, Dropdown, Radio, fSelect, and the Color facet, have a “Parent term” setting. This setting is only visible if the facet’s selected data source is a taxonomy. If you enter a parent term ID (here’s how to find it), the facet will only display the child terms of that specific term. If you need more control over which term levels are shown, you can use the facetwp_index_row hook. For example, to show only specific term levels, or to show only children of multiple parent terms.

Other facet types are specifically meant to be used with a hierarchical taxonomy as their data source. The Hierarchy facet lets users navigate through the separate term levels. And the Hierarchy Select facet, which has a dropdown for each hierarchical level:

FacetWP Hierarchy facet
The Hierarchy facet
FacetWP Hierarchy Select facet
The Hierarchy Select facet

The “Hierarchical” setting

The 'Hierarchical' facet setting, available when a taxonomy is chosen as data source, in Checkboxes, Dropdown, and fSelect facets.
The “Hierarchical” facet setting, available when a taxonomy is chosen as data source, in Checkboxes, Dropdown, and fSelect facets.

For Checkboxes, Dropdown and fSelect facets, if a taxonomy is selected as data source, a “Hierarchical” setting will become visible (for both hierarchical taxonomies and non-hierarchical taxonomies).

If this setting is enabled, and the taxonomy is actually a hierarchical taxonomy, the facet will visually show the hierarchy of the taxonomy terms in the facet’s choices, by ordering the child terms below their parent term and by indenting the child terms.

Part of a hierarchical Checkboxes facet, with expanded child levels.
Part of a hierarchical Checkboxes facet, with expanded child levels.

For example, let’s assume a Checkboxes facet with a taxonomy “location” set as its data source. This taxonomy has five hierarchical levels, from continents to countries, cities, boroughs, and areas.

If this facet has its “Hierarchical” setting enabled and if there are posts indexed for each term, the facet will look like the image on the right, with all child levels expanded.

The child levels will be collapsible with [+] / [-] icons. By default, all child levels will be in the collapsed state and can be expanded with the [+] icons. With the extra “Show expanded” setting enabled, child levels can be shown as expanded all the time. And if you want to hide the expand/collapse icons in this case, you can do so with one line of CSS.

Results filtering with hierarchical facets

The relationship between facets with a (hierarchical) taxonomy as data source and the filtered results is often a source of confusion.

What happens, for example, if you select a parent term in the facet? Will the results contain posts that have only that parent’s child term selected?

This is determined by how term hierarchies are indexed:

Indexing of term hierarchies

Posts with only the Paris term selected in the back-end will be displayed in the front-end results if you select Europe or France in the facet.
Posts with only the Paris term selected in the back-end will be displayed in the front-end results if you select “Europe” or “France” in the facet.

With the “Hierarchical” setting enabled, FacetWP automatically indexes both explicit and implicit term hierarchies.

This means that if your taxonomy includes Europe > France and a post has only the France term selected, then Europe will get indexed too for that post.

On the front-end this means that if you have a post that has only the Paris term selected, but not its parent terms (France or Europe), the post will still be displayed in the results if you filter by “Europe”, or “France” in the facet.

When to re-index term hierarchies

You do not have to re-index after editing an individual item (post, page, and category or term name/slug). When a post or term is saved, an automatic single re-index for that specific term/post is done. This keeps the index up to date, without putting the heavy burden of a full re-index on your site.

However, there are a few specific situations in which you do need to re-index after a change to categories or terms:

  • When a category or term’s hierarchy has changed. For example, after changing a term’s parent term.
  • When a category or term’s custom field content has changed. (Terms can have custom fields added by Advanced Custom Fields or Pods).

Note that there are more situations that would require re-indexing.

Customize which terms or levels are displayed in a facet

There are many scenarios in which you may want a hierarchical facet to display only a part of the entire term hierarchy, sometimes depending on the context in which the facet is displayed, like on a term archive page.

This can be done by making sure FacetWP only indexes a part of the term hierarchy, as demonstrated in the examples below.

Index only child terms of a specific parent

Index only children of a parent with term ID 46.
Index only children of a parent with term ID 46.

If you only want to display the child terms of a specific parent term, you can use the built-in “Parent term” setting of the facet, which is available in the Checkboxes, Dropdown, Radio, fSelect, and the Color facet.

Look up the parent’s term ID and enter it in the “Parent term” setting. Save the facet settings, and click the Re-index button.

For facet types that do not have this setting, you can use the facetwp_index_row hook.

Note that if you have a category/tag/taxonomy term archive page with a facet on it that uses the same hierarchical category/tag/taxonomy set as its data source, and you want your facet to only display choices that have the current term archive’s term as parent, see the solution below.

Index only specific term levels

Hierarchical taxonomy depth levels.
Hierarchical taxonomy depth levels.

If you want your facet to display only certain levels of the term hierarchy, you can use the facetwp_index_row hook.

Because this hook has access to the depth level of each term as it is being indexed (with $params['depth']), you can define which depth levels of the hierarchy are included or excluded.

The following code examples have to be added to your (child) term’s functions.php. Make sure to re-index after adding and editing them.

The first example below will index only the top-level terms (with depth == 0). To accomplish that, terms with depth levels > 0, which are all child levels, are excluded from being indexed by setting $params['facet_value'] to an empty string. Using the example taxonomy on the right, only “North America” and its sibling terms will be shown in the facet:

How to use custom PHP code?

PHP code can be added to your (child) theme's functions.php file. Alternatively, you can use the Custom Hooks add-on, or a code snippets plugin. More info

add_filter( 'facetwp_index_row', function( $params, $class ) { if ( 'my_facet_name' == $params['facet_name'] ) { // replace 'my_facet_name' with the name of your facet if ( $params['depth'] > 0 ) { $params['facet_value'] = ''; // don't index this row } } return $params; }, 10, 2 );

To index only the top-level terms (depth == 0) and their direct children (depth == 1):

How to use custom PHP code?

PHP code can be added to your (child) theme's functions.php file. Alternatively, you can use the Custom Hooks add-on, or a code snippets plugin. More info

add_filter( 'facetwp_index_row', function( $params, $class ) { if ( 'my_facet_name' == $params['facet_name'] ) { // Replace 'my_facet_name' with the name of your facet. if ( $params['depth'] > 1 ) { $params['facet_value'] = ''; // Don't index this row. } } return $params; }, 10, 2 );

The above examples exclude (lower) child levels from being indexed. It is also possible to exclude (higher) parent levels and keep child levels, by setting $params['depth'] > x to be indexed only. Or to keep only a child level, but not their parents or children, by setting $params['depth'] === x to be indexed only.

Three examples of this are shown below. Note that when higher levels are excluded, all lower levels that are indexed need to shift upward in the term hierarchy so that the highest included child level now becomes level 0. The example code in all snippets below accounts for that.

Use the following to index only direct child terms (depth == 1) and deeper levels. In other words, to skip the top-level terms (depth == 0):

How to use custom PHP code?

PHP code can be added to your (child) theme's functions.php file. Alternatively, you can use the Custom Hooks add-on, or a code snippets plugin. More info

add_filter( 'facetwp_index_row', function( $params, $class ) { if ( 'my_facet_name' == $params['facet_name'] ) { // replace 'my_facet_name' with the name of your facet. if ( $params['depth'] > 0 ) { $params['depth'] = $params['depth'] - 1; // Shift the depth level one upwards for every child level. } else { $params['facet_value'] = ''; // Don't index the highest level. } } return $params; }, 10, 2 );

To index only terms on a specific depth, including all children at lower levels, you can use the following snippet. Make sure to set the desired level in line 3. Note that the top level is 0, so 2 in this example is the grandchild level, three levels deep:

How to use custom PHP code?

PHP code can be added to your (child) theme's functions.php file. Alternatively, you can use the Custom Hooks add-on, or a code snippets plugin. More info

add_filter( 'facetwp_index_row', function( $params, $class ) { if ( 'my_facet_name' == $params['facet_name'] ) { // Replace 'my_facet_name' with the name of your facet $depth = 2; // Set the desired depth to show, including its children. The top level is 0, so 2 is grandchild level. if ( $params['depth'] >= $depth ) { $params['depth'] = $params['depth'] - $depth; // Shift the depth level one upwards for every child level. } else { $params['facet_value'] = ''; // Don't index this row. } } return $params; }, 10, 2 );

To index only the first-level direct child terms (depth == 1), but not their parent or child terms:

How to use custom PHP code?

PHP code can be added to your (child) theme's functions.php file. Alternatively, you can use the Custom Hooks add-on, or a code snippets plugin. More info

add_filter( 'facetwp_index_row', function( $params, $class ) { if ( 'my_facet_name' == $params['facet_name'] ) { // Replace 'my_facet_name' with the name of your facet. if ( $params['depth'] === 1 ) { $params['depth'] = $params['depth'] - 1; // Shift the depth level one upwards for every child level. } else { $params['facet_value'] = ''; // Don't index the highest level. } } return $params; }, 10, 2 );

Combine the “Parent term” setting with indexing specific term levels

Index only children of a parent with term ID 46.
Index only children of a parent with term ID 46.
Shifted depth levels with term ID 46 set in the 'Parent term' setting.
Shifted depth levels with term ID == 46 set in the “Parent term” setting.

It is possible to set a parent term in the facet’s setting, while at the same time limiting indexing to certain hierarchy levels.

But when using the above code examples, be aware that the depth levels will shift as soon as you set a “Parent term” in the facet’s setting. The direct child terms of that parent term will now have a depth of 0, their children will be 1, etc.

So if you set term ID 46 as “Parent term”, and use the second code example above to index only depth levels 0 and 1, the facet will only show “New York” and “Manhattan”.

Index only children of one or more parents

To display only child terms of one specific parent term in a facet, you can use the “Parent term” setting (if the facet type has this setting).

To do this programmatically, or to display only child terms of multiple parents, add the following code to your (child) theme’s functions.php.

Add the parent ID(s) of which you want the child terms to be shown to the array in line 5. Make sure to re-index after adding or changing the code.

How to use custom PHP code?

PHP code can be added to your (child) theme's functions.php file. Alternatively, you can use the Custom Hooks add-on, or a code snippets plugin. More info

add_filter( 'facetwp_index_row', function( $params, $class ) { if ( 'my_facet_name' == $params['facet_name'] ) { // Replace 'my_facet_name' with the name of your facet. $parent_id = [ 305,306 ]; // List all parents of which the child terms should be shown. Can be one or more. $taxonomy = str_replace( 'tax/', '', $params['facet_source'] ); // Get the taxonomy used as the facet data source $ancestors = get_ancestors( $params['term_id'], $taxonomy ); // Get all ancestors of the term being indexed. $term_id_parents = array_intersect( $parent_id, $ancestors ); // Get the parent id(s) are among the ancestors. if ( $term_id_parents ) { // If the parent(s) is/are among the ancestors $term_id_parent = end( $term_id_parents ); // Store the highest level parent id (in case there are more) $parent_depth = count( get_ancestors( $term_id_parent, $taxonomy ) ); // Get parent depth $params['depth'] = $params['depth'] - ( $parent_depth + 1 ); // Shift the depth level based on the depth of the parent id } else { $params['facet_value'] = ''; // Don't index this row. } } return $params; }, 10, 2 );

A few things to keep in mind when using the above code:

  • For this code to work, the data source of the facet needs to be a taxonomy. The code will work with or without the facet’s Hierarchical setting enabled.
  • Make sure not to use the facet’s “Parent term” setting.
  • If you add multiple parent IDs that are at different hierarchical levels, each of their child trees is shifted upwards in the hierarchy until the highest child level is at level 0. The tree may then look different than the original one.
  • If you add parent IDs that are within the same vertical parent-child tree, the code takes the highest one in the hierarchy and shows the children of that parent.

Use FacetWP on taxonomy term archives

The instructions for using FacetWP on taxonomy term archive templates are no different than for any other type of WP archive template . If you place facets on an existing WP archive template, FacetWP will automatically detect the right query and post loop, and your facets will “just work”.

In some cases, FaceWP’s automatic query detection can fail. If this happens, follow these troubleshooting steps.

Use Listing Builder listing shortcode on a taxonomy term archive

You may be tempted to place a Listing Builder listing shortcode on a taxonomy term archive, in order to customize the query, or to make use of the Listing Builder’s display features.

Generally, on WP archive pages, it would be better to not use shortcode templates but to use the WP archive template query itself (and if necessary, customize the archive query). Shortcode templates can best be placed on single pages or posts.

But if you want to keep using a Listing Builder listing shortcode on a taxonomy term archive, keep the following in mind.

Pre-filter Listing Builder listing templates for the current term

For each (custom or built-in) taxonomy, a term archive page exists for each term in the taxonomy. But your Listing Builder query will not automatically pre-filter for posts that use the current term archive page’s term; it will just return all posts of the post type(s) you have set in its query settings. In theory, you could create a separate Listing Builder template for each term archive, but that would be very impractical, as you will often have many terms in each taxonomy, and you’d have to make a new listing template each time you add a term.

Fortunately, FacetWP has the facetwp_template_use_archive hook which lets your Listing Builder query pre-filter the returned posts based on the current term archive page’s term, by injecting it into the shortcode template’s query arguments when filtering.

For example, on the category.php archive template, you could place a listing template shortcode that fetches all posts. Without this hook in place, on the /category/events term archive page, after using facets, the filtered results will be fetched from all posts, including posts that are not in the category events. With this hook in place, the results will only contain posts within the category events.

To use this hook, add the following code to your (child) theme’s functions.php:

How to use custom PHP code?

PHP code can be added to your (child) theme's functions.php file. Alternatively, you can use the Custom Hooks add-on, or a code snippets plugin. More info

add_filter( 'facetwp_template_use_archive', '__return_true' );

However, there is one catch when using this hook: WP’s native term archive query will still be used before filtering, because FacetWP’s automatic query detection by default will always prioritize the archive query ahead of any other query on the page. This may lead to differences before and after filtering caused by query arguments other than the current taxonomy term.

For example, you may see a different number of paged results before and after filtering, caused by the posts_per_page query argument in the native term archive query being different than the one in the shortcode query. Similarly, there may be differences caused by the order and orderby query arguments not being the same.

See the hook’s documentation page for two ways of fixing this.

Using a (hierarchical) taxonomy facet on a term archive page

A common scenario is that you have a category, tag, or taxonomy term archive page, with a facet that uses the same category/taxonomy as its data source.

Wouldn’t it be nice if that facet “knows” on which term archive page it lives, and if it would pre-select the “current” term’s choice? And even better, if it would only display choices from the term hierarchy that have the current term as parent?

Both are possible with a bit of custom code, as shown below. The following solutions can also be combined.

Pre-select the current term’s facet choice

Events category pre-selected in a categories facet
Pre-select events on the events term archive page

For example, say you have a category archive page /category/events/, on which you have a facet named categories which has categories (technically the category taxonomy) as data source, and you want the facet choice “events” to be pre-selected automatically.

The following code uses the facetwp_preload_url_vars hook to pre-select the current term’s corresponding choice in the facet. Add it to your (child) theme’s functions.php, and adapt the facet name in line 4 and line 6, and the taxonomy slug in line 3.

Note that this code will only work when the category/tag/term slug (events in this example) is the same as the facet value (which can be seen in the URL when you select the facet choice: /category/events/?categories=events). The slug also needs to be the last part of the URI. The URI is the part of the URL after the domain name, without slashes at the beginning or end, and without the query variables. In this example: category/events.

How to use custom PHP code?

PHP code can be added to your (child) theme's functions.php file. Alternatively, you can use the Custom Hooks add-on, or a code snippets plugin. More info

// Change 'categories' to the name of the categories/terms facet (2x) add_filter( 'facetwp_preload_url_vars', function( $url_vars ) { if ( false !== strpos( FWP()->helper->get_uri(), 'category' ) ) { // Change 'category' whatever the main URL slug is for the taxonomy term archive if ( empty( $url_vars['categories'] ) ) { $term = basename( FWP()->helper->get_uri() ); $url_vars['categories'] = [$term]; } } return $url_vars; } );

Pre-select a facet choice after a reset

If you are using a Reset facet, the pre-selected option will be deselected again after a reset.

The following code (p)re-selects that option again when a user clicks the Reset button/link:

How to use custom PHP code?

PHP code can be added to your (child) theme's functions.php file. Alternatively, you can use the Custom Hooks add-on, or a code snippets plugin. More info

<?php add_action( 'facetwp_scripts', function() { ?> <script> document.addEventListener('facetwp-loaded', function() { if (! FWP.loaded && false !== FWP_HTTP.uri.indexOf('category')) { // Change 'category' whatever the main URL slug is for the taxonomy term archive let term = FWP_HTTP.uri.split('/').reverse()[0]; FWP.hooks.addAction('facetwp/reset', function() { FWP.facets['categories'] = [term]; // Change 'categories' to the name of the categories/terms facet }); } }); </script> <?php }, 100 );

Only display facet choices that are children of the current term

If you have a category/tag/taxonomy term archive page with a facet on it that uses the same hierarchical category/tag/taxonomy set as its data source, the facet will display all choices (terms) for which posts on that page have been indexed. And as posts can have multiple terms selected, this can include terms anywhere in the taxonomy’s term hierarchy, not only children of the archive’s current term.

A common question is how to let the facet display only child terms of the archive’s current term (with or without the current term itself)?

This is currently not built into FacetWP as an option. There are a few ways to accomplish this:

Manually create a facet for each term archive

If you only have a very limited number of terms, you could make a separate facet for each term archive page, and use the “Parent term” setting to pre-select the term archive’s term for each facet.

In most situations, manually creating a facet for each term archive would be very impractical, as you will often have many terms in each taxonomy, and you’d have to make a new facet each time you add a term. Below are two approaches to this situation.

Remove all terms that are not a child term of the current term
For a facet with a hierarchical location taxonomy on the /category/new-york term archive page, how to only show New York and its child terms (purple frame), and pre-select New York? Or, only show its child terms (green frame)?
For a facet with a hierarchical location taxonomy on the /category/new-york term archive page, how to only show New York and its child terms (purple frame), and pre-select New York? Or, only show its child terms (green frame)?

The easiest solution is to use the same facet on each term archive page (without setting a “Parent term”) and to combine it with the following code.

The code uses the facetwp_facet_render_args hook to dynamically remove all terms from the facet that are not a child term of the current term. This will result in the facet displaying only child terms, on all hierarchical levels below the archive’s current term. If you want the facet to display only the direct child level, replace the if statement on line 25 with the alternative one on line 28.

This code works with the following facet types: Checkboxes, Dropdown, Radio, fSelect and Hierarchy Select. It does not work with Hierarchy facets, which do not have term_id and parent_id in their arguments.

The code assumes a hierarchical taxonomy, but it will work both with the facet’s “Hierarchical” setting enabled and disabled.

Add the code to your (child) theme’s functions.php. Change my_taxonomy_name in line 3 to the name of your taxonomy, and my_facet_name in line 4 to the name of your facet.

If you want the facet to include the archive’s term, in line 5 set $keep_current_term to true. When you do this, the current term is available to automatically pre-select it in the facet on page load, and again after a reset.

How to use custom PHP code?

PHP code can be added to your (child) theme's functions.php file. Alternatively, you can use the Custom Hooks add-on, or a code snippets plugin. More info

<?php add_filter( 'facetwp_facet_render_args', function( $args ) { $taxonomy = 'my_taxonomy_name'; // Change 'my_taxonomy_name' to the name of your taxonomy $facet = 'my_facet_name'; // Change 'my_facet_name' to the name of your facet $keep_current_term = false; // Set this to true if you want to include the current term if ( $facet == $args['facet']['name'] && is_tax( $taxonomy ) ) { // Exclude the Hierarchy facet if ( in_array( $args['facet']['type'], [ 'hierarchy' ] ) ) { return $args; } $current_term = get_queried_object_id(); if ( ! empty( $args['values'] ) ) { $current_term_depth = '0'; foreach ( $args['values'] as $key => $val ) { $term_id = $val['term_id']; if ( intval( $term_id ) === $current_term ) { $current_term_depth = intval( $val['depth'] ); } // This keeps sub-terms of the current term archive page if ( $val['parent_id'] && in_array( $current_term, get_ancestors( $val['term_id'], $taxonomy, 'taxonomy' ) ) ) { // Alternative if-statement: only keep direct children of the current term, no deeper level children: // if ( $val['parent_id'] == $current_term ) { continue; // This keeps parent term for current archive page } else if ( $keep_current_term && $current_term == $val['term_id'] ) { -- $current_term_depth; continue; } else { unset( $args['values'][ $key ] ); } } // Shift depths after deleting values $depthshift = ++ $current_term_depth; array_walk( $args['values'], function( &$item ) use ( & $depthshift ) { $newdepth = intval( $item['depth'] ) - $depthshift; $item['depth'] = (string) $newdepth; } ); $args['values'] = array_values( $args['values'] ); } } return $args; } );
Dynamically create a facet for each term archive

Another, more complicated approach could be to programmatically create facets for all the parent terms you need, with the facetwp_facets hook. And then to conditionally display the correct facet in your term archive template. Depending on how automated you need this process to be, you may also need to programmatically trigger a full re-index for each new facet added. Or you could use WP-CLI indexing, with which you can trigger indexing for specific facets only.

It is possible to let term archive links automatically redirect to a page with a facet that is automatically pre-selected for the clicked term.

Say you have a list of term links on your site, generated using get_term_link(). For example, a list of categories, like this:

How to use custom PHP code?

PHP code can be added to your (child) theme's functions.php file. Alternatively, you can use the Custom Hooks add-on, or a code snippets plugin. More info

$terms = get_terms('category'); echo '<ul>'; foreach ($terms as $term) { echo '<li><a href="'.get_term_link($term->slug, 'category').'">'.$term->name.'</a></li>'; } echo '</ul>';

With WP’s term_link hook, which filters the get_term_link() link URL output in line 4 above, you can now redirect these term links to a page with a facet that has that same taxonomy (category in this example) as data source, and let the facet be pre-selected based on the clicked term link.

The following example redirects /category/ archive links to a /blog/ page with a “categories” facet pre-selected for the clicked category archive link. So a /category/events/ link will redirect to /blog/?_categories=events, resulting in the “categories” facet on that page to be pre-selected with the “events” choice:

How to use custom PHP code?

PHP code can be added to your (child) theme's functions.php file. Alternatively, you can use the Custom Hooks add-on, or a code snippets plugin. More info

add_filter( 'term_link', function( $termlink, $term, $taxonomy ) { if ( 'category' == $taxonomy ) { // Replace 'category' with the name of your taxonomy $termlink = '/blog/?_categories=' . $term->slug; // Replace 'categories' with the name of your taxonomy-based facet } return $termlink; }, 10, 3);

See also

Last updated: November 27, 2025