Query Filter: Add Parent, Child of options for Taxonomy - Terms filter

Hi,
Currently we have the Filter Elements:

  • Fitler - Checkbox
  • Filter - Radio
  • Filter - Select

These Filter Elements can choose the Source as Taxonomy, for example I choose Post Category / Product Category. Everything is fine.

But I have a practical requirement to do on the following projects, my Taxonomy Category (Or Product Category) has the following hierarchical Terms:

A - Root
-- A - 1
-- A - 2
-- A - 3
-- A - 4
B - Root
-- B - 1
-- -- B - 1.1
-- -- B - 1.2
-- -- B - 1.3
-- B - 2
-- B - 3
C - Root

I need the Filter - Checkbox or Filter - Radio or Filter - Select to list only the child Terms of a parent Terms. For example, I just want to display a list of “chips”:
A - 1, A - 2, A - 3, A - 4. (There are actually a lot of them and they are dynamic update.)
With Bricks’ Query Loop, we can do that easily. But with the current Taxonomy query option, Query Filter, it is not yet. Please see the 2 attached images below.

Query Loop: Taxonomy query have Parent and Child of

Query Filter:

If there is any way to solve this issue using PHP (Hook, Filter), I would appreciate your help.
I hope Bricks Builder will add this feature to Query Filter in the near future.

Thanks
:bear:

4 Likes

Bumping this up, as I came across a need of exactly that functionality!

In filter element, when choosing taxonomy → category, we should be able to choose “parent” and “child of”.

For example Parent {term_id}, so we only display sub-categories of the current term.

Then we can nicely filter a category by its sub-categories.

Please try to add to the next release.

Keep us posted, thanks!

P.S - @datgausaigon Did you manage to come up with a workaround solution?

1 Like

Hi, @matt-cnc

I am currently using the exclude feature. I have to temporarily exclude each category that should not appear in the one that should appear. It’s very hard, but let’s deal with it like this for now because I have no other way at the moment. I think there is a way with PHP, but I haven’t had time to look into it yet.

Thanks
:bear:

2 Likes

Hey @christian,

Unfortunately not :frowning:

Temporarily, I have decided to display the sub-categories above the filter with just simple query loop.

However, I will probably add it under the Filter with a checkbox element, as soon as we will be able to choose “parent” and “child of” in filter element taxonomies.

@timmse - do you know if this functionality is in the roadmap?

Thanks!

1 Like

Hi all.

Any solution so far to this problem? Have you resorted to plugins, php or an update I need to check?

Thanks!

1 Like

I can add ‘Parent/Child of’ setting with filters but something wonky going on. It works perfectly with static id but dynamic data like {term_id} works only on initial load. Changing the filter reloads it with ajax after which it ignores it.

add_filter( 'bricks/filter_element/controls', function( $controls, $element ) {
    $new_controls = [
        'parent' => [
            'type'        => 'number',
            'label'       => esc_html__( 'Parent', 'bricks' ),
            'inline'      => true,
            'hasDynamicData' => true,
			'required' => [
				[ 'filterSource', '=', 'taxonomy' ],
			],
        ],
        'child_of' => [
            'type'        => 'number',
            'label'       => esc_html__( 'Child of', 'bricks' ),
            'inline'      => true,
            'hasDynamicData' => true,
			'required' => [
				[ 'filterSource', '=', 'taxonomy' ],
			],
        ],
    ];

    // Insert the new controls after the 'filterTermTopLevel' control
    $offset = array_search( 'filterTermTopLevel', array_keys( $controls ) );
    $controls = array_slice( $controls, 0, $offset + 1, true ) + $new_controls + array_slice( $controls, $offset + 1, null, true );

    return $controls;
}, 10, 2 );


add_filter( 'bricks/filter/taxonomy_args', function( $args, $element ) {
    $settings = $element->settings;

    if ( !empty( $settings['parent'] ) ) {
        $args['parent'] = bricks_render_dynamic_data( $settings['parent'] );
    }

    if ( !empty( $settings['child_of'] ) ) {
        $args['child_of'] = bricks_render_dynamic_data( $settings['child_of'] );
    }

    return $args;
}, 10, 2 );
1 Like

Hi all,

I see this new Filter in version 2.0.2. Do you think it can help us solve this issue?

The bricks/filter_element/populated_options PHP filter allows you to modify the populated options of Filter – Select, Filter – Radio, and Filter – Checkbox elements before they are rendered into HTML. (@since 2.0.2)

This is useful if you want to:

  • Add/remove certain options
  • Reorder options (based on complicated custom requirement)
  • Change display text or values

Thanks
:bear:

Hi,
You can try with new filter in Bricks Builder 2.0.2

add_filter( 'bricks/filter_element/populated_options', function ( array $options, $element ) {
	if ( $element->id !== 'yourFilterId' ) {
		return $options;
	}

	$taxonomy         = 'category';
	$parent_term_slug = 'b-root';

	$parent = get_term_by( 'slug', $parent_term_slug, $taxonomy );
	if ( ! $parent || is_wp_error( $parent ) ) {
		return $options;
	}

	$only_direct_children = false;
	if ( $only_direct_children ) {
		$children      = get_terms( [
			'taxonomy'   => $taxonomy,
			'parent'     => $parent->term_id,
			'hide_empty' => false,
		] );
		$allowed_ids   = wp_list_pluck( $children, 'term_id' );
		$allowed_slugs = wp_list_pluck( $children, 'slug' );
	} else {
		$descendant_ids = get_term_children( $parent->term_id, $taxonomy );
		if ( is_wp_error( $descendant_ids ) || empty( $descendant_ids ) ) {
			return [];
		}

		$descendants   = get_terms( [
			'taxonomy'   => $taxonomy,
			'include'    => $descendant_ids,
			'hide_empty' => false,
		] );
		$allowed_ids   = array_map( 'intval', $descendant_ids );
		$allowed_slugs = wp_list_pluck( $descendants, 'slug' );
	}

	$options = array_values( array_filter( $options, function ( $opt ) use ( $allowed_ids, $allowed_slugs ) {
		if ( ! empty( $opt['is_all'] ) || ! empty( $opt['is_placeholder'] ) ) {
			return false;
		}
		
		$val = $opt['value'];
		
		if ( is_numeric( $val ) ) {
			return in_array( (int) $val, $allowed_ids, true );
		}

		return in_array( (string) $val, $allowed_slugs, true );
	} ) );

	return $options;
}, 10, 2 );

Thanks
:bear: