Using the Twig map-filter

Code

January 6, 2020

A fairly difficult to use filter is the map-filter, but it is very useful for WP Terms, repeaters and other objects.

Using map-filter for Terms

Let’s start with a simple example first and break it down:

{{ post.terms|map( item => "#{item.name}" )|join( ", " ) }}

Let’s assume the post variable is set as the Timber Post, so either by a toolboxtwig shortcode, a (Beaver Builder) Timber Posts Module or a Toolbox Field Module.

  • First, notice we can directly echo, so we use {{ }} to output our filtered results.
  • post.terms is an object with 0 (zero) to n iterations
  • |map( item => "#{item.name}" ) maps each iteration of said object found in post.terms to the variable name item
  • item => "#{item.name}" the object is reset to the string value of it’s subitems variable .name
  • This means we now have an array of string-values, each one the term.name only.
  • |join( ", " ) returns the array concatenated, using “, ” between each iteration.

Using map-filter for posts

When displaying posts you would usually resort to a {% for item in posts %} {% endfor %} kind of solution, but you can also use a one-liner like this:

{{ posts|map( item => "<p><a href=\"#{ item.link }\">#{item.title}</a></p>" )|join( "" ) }}

Here we use |join(""), which deliberately has nothing between the quotes and is used to output the mapped items as concatenated strings.

Using macros to creating more complex map-items

Now that we know that we can map each iteration to a variable (we have used item as the variable name so far, but you can use a different name too, i.e. n, i, my_item), we can try to do some more complex mapping:

{% import _self as macros %}
{{ posts|map( item => macros.test_length( item ) )|join( '' ) }}
{#

#}
{% macro test_length( item )%}
{% if item.title|length > 10 %}<p>{{item.title}}</p>{% endif %}
{% endmacro %}

We add a macro to the twig template and use {% import _self as macros %} to import all macros on _self (the twig template) as the macros variable. Now we have a way to return empty strings if the title is not long enough.

Note: the number of items is actually still the same, but some will be “empty”, so to speak.

Beaverplugins

Web ninja with PHP/CSS/JS and Wordpress skills. Also stand-in server administrator, father of four kids and husband to a beautiful wife.
Always spends too much time figuring out ways to do simple things even quicker. So that you can benefit.