MdMasud

WordPress, Laravel, Flutter

How to Group Hierarchical WordPress Taxonomy Terms in a Select Dropdown Without Extra SQL Queries

·

, ,

If you’re building a custom dropdown menu for a hierarchical taxonomy in WordPress — for example, letting users choose a role or category — you might want to:

  • Show parent terms as group labels (like <optgroup>)
  • Show **child terms as selectable <option>s
  • Include terms that aren’t attached to any posts
  • Avoid running SQL queries inside loops

Seems simple, right? But it’s trickier than it looks.

Let me show you the cleanest way to build it — no unnecessary queries, no missing terms, and no over-complicated logic.

The Issue

If you use get_terms() and loop through the results, it’s tempting to grab each parent and then call get_terms() again to fetch its children.

$parents = get_terms([... 'parent' => 0 ...]);

foreach ($parents as $parent) {
    $children = get_terms([... 'parent' => $parent->term_id ...]); // Inefficient
}

This works — but it creates a new SQL query for every parent term. That’s a classic performance problem, especially on larger sites.

The Efficient Solution

Instead, just call get_terms() once — and group the results in PHP.

Here’s the 10-line approach that avoids all the extra queries:

$grouped_terms = [];
$terms = get_terms(['taxonomy' => 'your_taxonomy', 'hide_empty' => false]);

if ($terms) {
    foreach ($terms as $term) {
        if ($term->parent == 0) {
            $grouped_terms[$term->term_id]['name'] = $term->name;
        } else {
            $grouped_terms[$term->parent]['children'][] = $term;
        }
    }
}

Its better way

  • Only one query to fetch all terms (parents + children)
  • No need to pre-sort the results
  • If a child term’s parent wasn’t processed yet, that’s okay — it’ll still get grouped
  • Even unused terms (not attached to posts) are included thanks to 'hide_empty' => false

Rendering the Select Dropdown

Now that you’ve grouped your terms, render the dropdown with <optgroup> for parents and <option> for children:

echo '<select name="your_field_name">';
foreach ($grouped_terms as $group) {
    if (empty($group['children'])) continue;

    $label = $group['name'] ?? 'Other';

    echo '<optgroup label="' . esc_html($label) . '">';
    foreach ($group['children'] as $child) {
        echo '<option value="' . esc_attr($child->term_id) . '">' . esc_html($child->name) . '</option>';
    }
    echo '</optgroup>';
}
echo '</select>';

This gives you a clean, user-friendly dropdown grouped by parent terms.

Use Cases

  • Admin filters in meta boxes
  • Frontend submission forms
  • Custom post type selectors (e.g. “Job Roles”, “Product Categories”)
  • Anywhere you want a taxonomy-based grouped select

When working with WordPress taxonomies, efficiency matters. Avoiding unnecessary SQL calls can make your plugins or themes faster, lighter, and more scalable.

This technique helps you build a clean, scalable dropdown for any hierarchical taxonomy — with zero extra queries, no missing terms, and just 10 lines of code.

Comments

Leave a Reply

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