Row edge-slant Shape Decorative svg added to bottom

Why I use macros for everything

Code

December 24, 2021

UIkit needed

Make sure to activate the UIkit CSS/JS setting in Toolbox Settings

Okay, so I get that this is a pretty spammy title. But Twig macros are just awesome to use all over your templates. They’re like the CSS-classes of HTML.

What is a macro?

A macro is a re-usable piece of code, sort of what a function is in PHP. A macro can be used directly in your template:

Twig
{% for i in 0..5 %}
    {{ _self.the_number( i ) }}
{% endfor %}


{% macro the_number( number ) %}
The current number is {{ number }}
{% endmacro %}

Notice the _self variable there, before calling the named macro. This means we are calling a macro that resides in our current template.

Code output:

The current number is 0
The current number is 1
The current number is 2
The current number is 3
The current number is 4
The current number is 5

Ready for more?

The example above is a very common pattern. But applied to WordPress posts, this is a something that you’d probably want applied across your entire site. A card layout for instance:

The concept is similar. This example first sets the posts variable with some dummy data, but right after we see the same pattern. It opens an

element and iterates over the posts, calling each iteration item. Then, it calls the ‘card’ macro, which is defined in the same template.

The macro takes one variable, the ‘item’. Note that everything else is scoped, which means that no other values that exist outside the macro are available.

Twig
 class="uk-child-width-1-2@s uk-grid-match" uk-grid>
{% for item in posts %}
    {{ _self.card( item ) }}
{% endfor %}
{% macro card( item ) %}
	 href="{{ item.link }}" class="uk-link-reset">
		 class="uk-card uk-card-default uk-height-1-1">
			 class="uk-background-cover uk-height-small uk-panel uk-flex uk-flex-center uk-flex-middle" style="background-image: url({{ item.thumbnail|default( 'https://picsum.photos/seed/200/300' ) }});">
			
class="uk-card-body"> class="uk-card-title">{{ item.title }} {{ item.preview.length(20).read_more( '' ) }}
{% endmacro %}

Using macros that are outside of our template

To really take advantage of macros, you can use the ones that are outside of our template. Let’s take our card example, and put that in a separate template:

Using the Twig Templates CPT, create a template called “card_macro” (make sure the slug has this value) and paste the following code inside the template:

Twig
{# filename: card_macro.twig #}
{% macro _render( item ) %}
	 href="{{ item.link }}" class="uk-link-reset">
		 class="uk-card uk-card-default uk-height-1-1">
			 class="uk-background-cover uk-height-small uk-panel uk-flex uk-flex-center uk-flex-middle" style="background-image: url({{ item.thumbnail|default( 'https://picsum.photos/seed/200/300' ) }});">
			
class="uk-card-body"> class="uk-card-title">{{ item.title }} {{ item.preview.length(20).read_more( '' ) }}
{% endmacro %}

Notice that I changed the name of the macro to ‘render’. This is because we will be using this macro in a way that mimics component rendering. Now let’s head back to our original template, add the macro and call it:

Twig
{# import the template file 'card_macro.twig' as a variable 'Card' #}
{% import 'card_macro.twig' as Card %}
 class="uk-child-width-1-2@s uk-grid-match" uk-grid>
  {% for item in posts %}
      {{ Card.render( item ) }}
  {% endfor %}

On the very first line, we are importing the macro-file as ‘Card’, with a capital ‘C’. This is helpful for identifying the ‘components’ from regular variables, so it’s certainly a practice that I would like to recommend.

In the loop, we are rendering the only macro available in ‘Card’, which is called ‘_render’.

Now, if we want to make a change to the Card layout, we would go to the ‘card_macro’ template and save it.

Using the card on other template parts

Now that we’ve set a base for our card, we can re-use this design on various other parts of our site. The beauty of it all is that – if we decide to change the layout of our card – it changes that sitewide!

We can use it in a modal for instance:

Twig
{% import 'card_macro.twig' as Card  %}

 class="uk-text-center">
     class="uk-button uk-button-default uk-margin-small-right" type="button" uk-toggle="target: #modal-close-default">
    OPEN MODAL
    
id="modal-close-default" class="uk-flex-top" uk-modal> class="uk-container-small uk-modal-dialog uk-margin-auto-vertical"> {% for item in posts %} {{ Card.render( item ) }} {% endfor %}