Skip to main content

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

ArgumentDescriptionExample
taxonomyTaxonomy name'category', 'post_tag', 'product_cat'
hide_emptyHide terms with no poststrue, false
orderbySort field'name', 'count', 'term_id', 'menu_order'
orderSort direction'ASC', 'DESC'
numberLimit results10
parentParent term ID (0 for top-level only)0
child_ofAll descendants of a term12
includeInclude specific IDs[1, 2, 3]
excludeExclude specific IDs[4, 5]
slugFilter 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 %}
<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 %}
{{ 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