I’m using isotope to filter a custom post type. But I only want the child taxonomies of 2 particular parents. I have it working nicely for one parent, but I’m not sure how to modify the array to allow for 2 parents.

$terms = get_terms('speight_plans', array('parent' => 16)); // you can use any taxonomy, instead of just 'category'
    $count = count($terms); //How many are they?
        if ( $count > 0 ){  //If there are more than 0 terms
            foreach ( $terms as $term ) {  //for each term:
                echo '<button class="button" data-filter=".'.$term->slug.'">' . $term->name . '</button>';
                //create a list item with the current term slug for sorting, and name for label
            }
        }

I tried doing

array('parent' => 16, 15));

But that still only showed the children of parent 16.

Any help you can afford would be much appreciated.

2 Answers
2

We can filter the generated SQL query through the terms_clauses filter before the SQL query is executed. What we will be doing is to introduce a new parameter called wpse_parents which will accept an array of parent term ID’s to get children from. Note, this new parameter works exactly the same as the build-in parameter, parent, as it will return only direct children of the parent.

THE FILTER

The code is commented for easy understanding and basic description of what a particular piece of code is doing. Note, all code requires at least PHP 5.4

add_filter( 'terms_clauses', function ( $pieces, $taxonomies, $args )
{
    // Bail if we are not currently handling our specified taxonomy
    if ( !in_array( 'speight_plans', $taxonomies ) )
        return $pieces;

    // Check if our custom argument, 'wpse_parents' is set, if not, bail
    if (    !isset ( $args['wpse_parents'] )
         || !is_array( $args['wpse_parents'] )
    ) 
        return $pieces;

    // If  'wpse_parents' is set, make sure that 'parent' and 'child_of' is not set
    if (    $args['parent']
         || $args['child_of']
    )
        return $pieces;

    // Validate the array as an array of integers
    $parents = array_map( 'intval', $args['wpse_parents'] );

    // Loop through $parents and set the WHERE clause accordingly
    $where = [];
    foreach ( $parents as $parent ) {
        // Make sure $parent is not 0, if so, skip and continue
        if ( 0 === $parent )
            continue;

        $where[] = " tt.parent="$parent"";
    }

    if ( !$where )
        return $pieces;

    $where_string = implode( ' OR ', $where );
    $pieces['where'] .= " AND ( $where_string ) ";

    return $pieces;
}, 10, 3 );

Just a note, the filter is build in such a way that it does not allow the parent and child_of parameters being set. If any of those parameters are set, the filter bails early and is not applied

BASIC USAGE

If you need to query child terms from terms 15 and 16, you can run the following query to achieve your goal

$args = [
    'wpse_parents' => [15, 16]
];
$terms = get_terms( 'speight_plans', $args );

Leave a Reply

Your email address will not be published. Required fields are marked *