Query Terms
This page covers how to query taxonomy terms — categories, tags, and custom taxonomies — using get_terms().
Arguments follow the WP_Term_Query API.
Basic usage
{% for term in get_terms({'taxonomy': 'category'}) %}
<a href="{{ term.link }}">{{ term.name }}</a>
{% endfor %}
Common arguments
| Argument | Description | Example |
|---|---|---|
taxonomy | Taxonomy name | 'category', 'post_tag', 'product_cat' |
hide_empty | Hide terms with no posts | true, false |
orderby | Sort field | 'name', 'count', 'term_id', 'menu_order' |
order | Sort direction | 'ASC', 'DESC' |
number | Limit results | 10 |
parent | Parent term ID (0 for top-level only) | 0 |
child_of | All descendants of a term | 12 |
include | Include specific IDs | [1, 2, 3] |
exclude | Exclude specific IDs | [4, 5] |
slug | Filter by slug(s) | 'news', ['news', 'updates'] |
Real-world patterns
Category navigation
<nav>
{% for term in get_terms({'taxonomy': 'category', 'hide_empty': true, 'orderby': 'name'}) %}
<a href="{{ term.link }}">{{ term.name }} ({{ term.count }})</a>
{% endfor %}
</nav>
Top categories by post count
{% for term in get_terms({
'taxonomy': 'category',
'orderby': 'count',
'order': 'DESC',
'number': 5,
'hide_empty': true
}) %}
<span class="tag">{{ term.name }}</span>
{% endfor %}
Product category grid
{% for term in get_terms({
'taxonomy': 'product_cat',
'hide_empty': true,
'parent': 0
}) %}
<div class="category-card">
<h3><a href="{{ term.link }}">{{ term.name }}</a></h3>
<span>{{ term.count }} products</span>
</div>
{% endfor %}
Hierarchical menu (parent + children)
{% for parent in get_terms({'taxonomy': 'location', 'parent': 0}) %}
<div class="menu-group">
<h3>{{ parent.name }}</h3>
{% for child in get_terms({'taxonomy': 'location', 'parent': parent.id}) %}
<a href="{{ child.link }}">{{ child.name }}</a>
{% endfor %}
</div>
{% endfor %}
Tag cloud
{% for term in get_terms({
'taxonomy': 'post_tag',
'orderby': 'count',
'order': 'DESC',
'number': 20,
'hide_empty': true
}) %}
<a href="{{ term.link }}" class="tag">{{ term.name }}</a>
{% endfor %}
Category filter with "all" link
<nav class="filter-bar">
<a href="/blog/" class="{{ not archive.term ? 'active' : '' }}">All</a>
{% for term in get_terms({'taxonomy': 'category', 'hide_empty': true}) %}
<a href="{{ term.link }}" class="{{ archive.term.id == term.id ? 'active' : '' }}">
{{ term.name }}
</a>
{% endfor %}
</nav>
Category index with posts
List each category with its latest posts underneath:
{% for term in get_terms({'taxonomy': 'category', 'hide_empty': true}) %}
<section>
<h2>{{ term.name }}</h2>
{% for post in get_posts({'category_name': term.slug, 'posts_per_page': 3}) %}
<a href="{{ post.link }}">{{ post.title }}</a>
{% endfor %}
</section>
{% endfor %}
Breadcrumb from parent chain
{{ term.parent ? term.parent.name ~ ' / ' : '' }}{{ term.name }}
If "Running Shoes" has parent "Shoes": Shoes / Running Shoes
Common mistake
hide_empty defaults to true in WordPress. If you're not seeing terms you expect, check whether they have published posts assigned. Set 'hide_empty': false to include empty terms.
Next steps
- Term provider — all fields available on term items
- get_posts() — query posts filtered by taxonomy
- Loop — loop concept and data sources