4

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

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 );
  • This was perfect! Thank you loads! I added the filter to my functions.php and integrated the arg into the code I already had. – Laura Sage Mar 25 '16 at 15:30
  • Glad it worked. Enjoy ;-) – Pieter Goosen Mar 26 '16 at 6:21
0

I can think about the get_term_children() function. You can use that function two times to retrieve 2 array of child terms id of two parent terms. Then you can merge them to one array and pass that array to get_terms

get_terms('speight_plans', array('include' => $child_terms_arr));

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.