Skip to main content
Timber

You are reading the documentation for Timber v2.x. Switch to the documentation for Timber v1.x.

Terms

Get a term #

To get a term object in Timber, you use Timber::get_term() and pass the WordPress term ID as an argument.

$term = Timber::get_term($term_id);

This function is similar to get_term() and accepts one argument: a term ID. If you don’t pass in any argument, Timber will use get_queried_object() to try and work with the currently queried term.

$term = Timber::get_term();

// Is the same as…

$term = Timber::get_term(get_queried_object_id());

What you get in return is a Timber\Term object, which is similar to WP_Term.

Get term by field #

If you don’t have a term ID, you can also get a term by other fields, like slug or name through Timber::get_term_by().

// Get a term by slug.
$term = Timber::get_term_by('slug', 'news', 'category');

// Get a term by name.
$term = Timber::get_term_by('name', 'News', 'category');

Twig #

You can convert terms IDs to term objects in Twig using the get_term() function.

{% set term = get_term(term_id) %}

If you have an array of terms IDs that you want to convert to Timber\Term objects, you can use get_terms().

{% for term in get_terms(term_ids) %}

{% endfor %}

Invalid terms #

If no valid term can be found with the term ID you provided, the Timber::get_term() function will return null. With this, you can always check for a valid term with a simple if statement.

$term = Timber::get_term($term_id);

if ($term) {
}

Or in Twig:

{% if term %}
{{ term.title }}
{% endif %}

Extending Timber\Term #

If you need additional functionality that the Timber\Term class doesn’t provide or if you want to have cleaner Twig templates, you can extend the Timber\Term class with your own classes:

class BookGenre extends Timber\Term
{
}

To initiate your new BookGenre term, you also use Timber::get_term().

$term = Timber::get_term($term_id);

In the same way that you can’t instantiate post objects directly, you can’t instantiate a Timber\Term object or an object that extends this class with a constructor. Timber will use the Term Class Map to sort out which class it should use.

Querying Terms #

If you want to get an array of terms, you can use Timber::get_terms().

$terms = Timber::get_terms();

If you don’t pass in any argument, Timber will use get_taxonomies() to get a list of terms from all taxonomies.

You can pass the same arguments to this function that you know from using WP_Term_Query.

// Using the WP_Term_Query argument format.
$terms = Timber::get_terms([
'taxonomy' => 'book_genre',
'count' => true,
]);

Also check out the documentation for Timber::get_terms().

You get array of terms as a return value that you can loop over.

foreach ($terms as $term) {
echo $term->title();
}

In Twig, you can do the same.

{% for term in terms %}
{{ term.title }}
{% endfor %}

When you query for terms, Timber will use the Term Class Map to check which class it should use to instantiate your terms.

Listing terms in Twig #

When you want to display your terms in a textual list, you can make use of Twig filters:

{# A comma separated list #}
{{ terms|join(', ') }}

You don’t have to provide {{ term.title }}, because when you use {{ term }}, Timber will automatically return a term’s title.

If you want to separate the last item in your list with something else than a comma, use the second argument in Twig’s join filter.

{{ terms|join(', ', 'and') }}

And now, you probably also want to link these terms as well. You can make use of Twig’s map filter. While we use a dot (.) in PHP to concatenate strings, we use the tilde (~) in Twig.

{{ terms|map(
term => '<a href="' ~ term.link ~ '">' ~ term.title ~ '</a>'
)|join(', ', ' and ') }}

Or you can use a for loop:

{% for term in terms -%}
<a href="{{ term.link }}">{{ term.title }}</a>
{{ not loop.last ? 1 == loop.revindex0 ? ' and ' : ', ' }}
{%- endfor %}

We make use of the loop variable in Twig to either display an and or a comma.

See how we end the opening tag of the for-loop with -%} and start the closing tag with {%-? These are Whitespace Controls and can come in quite handy. Here, we use them to remove all the superfluous markup whitespace we don’t need.## Get terms from a post collection

Get terms from a post collection #

When working with a collection of posts (via Timber::get_posts()), you can get all the terms that are associated with those posts using the terms() method. This is useful for creating taxonomy filters, tag clouds, or displaying all terms used across a set of posts.

$posts = Timber::get_posts([
'post_type' => 'article',
'posts_per_page' => 20,
]);

// Get all terms from all taxonomies used by these posts
$all_terms = $posts->terms();

// Get only categories
$categories = $posts->terms('category');

// Get multiple taxonomies, grouped by taxonomy name
$terms_by_taxonomy = $posts->terms(['category', 'post_tag'], ['merge' => false]);

In Twig, you can use the same approach:

{# Get posts #}
{% set posts = get_posts({
post_type: 'project',
posts_per_page: 10
}) %}


{# Display all categories used in these posts as filter links #}
<div class="filters">
{% for category in posts.terms('category') %}
<a href="{{ category.link }}" class="filter-link">
{{ category.name }}
</a>
{% endfor %}
</div>

{# Or group terms by taxonomy #}
{% set terms_by_tax = posts.terms('all', {merge: false}) %}
{% for taxonomy, terms in terms_by_tax %}
<h3>{{ taxonomy|title }}</h3>
<ul>
{% for term in terms %}
<li><a href="{{ term.link }}">{{ term.name }}</a></li>
{% endfor %}
</ul>
{% endfor %}

Parameters #

The terms() method accepts two parameters:

$query_args (string|array) – Optional. Default: []

  • A taxonomy slug as a string: 'category'
  • An array of taxonomy slugs: ['category', 'post_tag']
  • A full WP_Term_Query arguments array with additional parameters

$options (array) – Optional. Default: []

  • merge (bool) – Whether to merge terms from all taxonomies into a single array (true, default) or return them grouped by taxonomy name (false)

Examples #

Get terms from a specific query

$featured_posts = Timber::get_posts([
'post_type' => 'post',
'meta_key' => 'featured',
'meta_value' => '1',
]);

// Get all tags used in featured posts
$featured_tags = $featured_posts->terms('post_tag');

Create a dynamic filter navigation

{% set posts = get_posts({category_name: 'news'}) %}

<nav class="tag-filters">
<h4>Filter by tag:</h4>
{% for tag in posts.terms('post_tag') %}
<a href="{{ tag.link }}">{{ tag.name }}</a>
{% endfor %}
</nav>

Get terms grouped by taxonomy

$posts = Timber::get_posts(['post_type' => 'article']);

// Get terms organized by taxonomy
$grouped_terms = $posts->terms('all', ['merge' => false]);

// $grouped_terms will be an array like:
// [
// 'category' => [Term, Term, ...],
// 'post_tag' => [Term, Term, ...],
// ]

This feature works on both PostQuery objects (when querying with WP_Query arguments) and PostArrayObject (when passing an array of post IDs or existing posts to Timber::get_posts()).