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()).