Wordpress - How to only list the child terms of a taxonomy and not their parents?
This should work for you:
$taxonomyName = "age";
//This gets top layer terms only. This is done by setting parent to 0.
$parent_terms = get_terms( $taxonomyName, array( 'parent' => 0, 'orderby' => 'slug', 'hide_empty' => false ) );
echo '<ul>';
foreach ( $parent_terms as $pterm ) {
//Get the Child terms
$terms = get_terms( $taxonomyName, array( 'parent' => $pterm->term_id, 'orderby' => 'slug', 'hide_empty' => false ) );
foreach ( $terms as $term ) {
echo '<li><a href="' . get_term_link( $term ) . '">' . $term->name . '</a></li>';
}
}
echo '</ul>';
You could also do:
$terms = get_terms($taxonomyName);
foreach($terms as $term) {
if ($term->parent != 0) { // avoid parent categories
//your instructions here
}
}
I've noted that parent have "parent" field equal to 0, and a child have his parent id in it.
We can exclude the top level parents by filtering them out by using the terms_clauses
filter to alter the SQL query before it executes. This way we do not need to skip parents in the final foreach
loop as they are not in the returned array of terms, this saves us unnecessary work and coding
You can try the following:
add_filter( 'terms_clauses', function ( $pieces, $taxonomies, $args )
{
// Check if our custom arguments is set and set to 1, if not bail
if ( !isset( $args['wpse_exclude_top'] )
|| 1 !== $args['wpse_exclude_top']
)
return $pieces;
// Everything checks out, lets remove parents
$pieces['where'] .= ' AND tt.parent > 0';
return $pieces;
}, 10, 3 );
To exclude top level parents, we can now pass 'wpse_exclude_top' => 1
with our array of arguments. The new wpse_exclude_top
parameter is supported by the filter above
$terms = get_terms( 'category', ['wpse_exclude_top' => 1] );
if ( $terms
&& !is_wp_error( $terms )
) {
echo '<ul>';
foreach ($terms as $term) {
echo '<li><a href="' . get_term_link( $term ) . '">' . $term->name . '</a></li>';
}
echo '</ul>';
}
Just a note, get_term_link()
do no not accept the term name, only, slug, ID or the complete term object. For performance, always always pass the term object to get_term_link()
if the term object is available (as in this case)