The Mijingo Blog

Latest news, updates, free tutorials, and more from Mijingo.

Using Macros in Twig and Craft

by Ryan Irelan

Macros are the Twig version of functions. Just like you would write a function in PHP to do something and return something, you can use a Twig macro to generate some output.

Macros are used for generating often used markup that might vary slightly each time. You put your skeleton markup in the macro and use parameters passed in to alter that markup and then output it.

Building a Twig Macro

A macro looks like this:


{% macro macroName(parameter1, parameter2) %}

    {# contents of the macro here #}

{% endmacro %}

Let’s take a look at an example for a list of social networking links that we want to include in several places on a site, but with different variations.

We’ll generate the list using a macro, so we can control which social networks are included, and add a class name to the ul element.

The first thing we need to do is define the data that we want to pass in to the macro. We’ll do that with a hash (more on Twig hashes).

The hash contains the information about each social network that we want to include in the list. Each network has a name and a URL. We set the hash to the variable networks.


{% set networks = {
    twitter: { name: "Twitter", url: "http://twitter.com/mijingo" },
    facebook: { name: "Facebook", url: "http://facebook.com/mijingo" },
    instagram: { name: "Instagram", url: "http://instagram.com/mijingo" }
    }
%}

Now, let’s build the macro. It’ll be our little factory for creating social link lists.


{% macro socialList(networks, className) %}
    <ul {% if className %}class="{{ className }}"{% endif %}>
    {% for network in networks %}
        <li class="{{ network.name | lower }}"><a href="{{ network.url }}">{{ network.name }}</a></li>
    {% endfor %}
    </ul>
{% endmacro %}

Let’s step through this macro line by line to understand what it does.

We’ll call the macro socialList. It takes two parameters; the first one is a hash of the networks we want to include, and the second one is the class name for the ul element.

The markup inside of the macro is an unordered list that outputs the list of social networks.

The class name is optional, and we add a conditional to only output a class name if one is passed in.

We use a for-loop to iterate over the hash passed in to the macro and then output a li element with the social network information for each social network.

In case we want to add additional styling or an icon, we populate the li elements with a class of the network name. We are taking the network name and passing it to the lower filter to make the name lowercase (another option would be to use the key name instead of lowercasing the network name).

So the links are clickable, the link to the social network is populated using the URL that is in the hash.

To wrap up, we close the for-loop and then close our ul element and, finally, close our macro tag.

Calling a Twig Macro

To call this macro right from the template it’s in, we use our output tags and the _self prefix on the macro name.

{{ _self.socialList(networks, "three-share") }}

This will call the socialList macro, passing in the networks hash, and the class name of three-share.

Our output will look something like this:


<ul class="three-share">
    <li class="twitter"><a href="http://twitter.com/happylager">Twitter</a></li>
    <li class="facebook"><a href="http://facebook.com/happylager">Facebook</a></li>
    <li class="instagram"><a href="http://instagram.com/happylager">Instagram</a></li>
</ul>

It’s not always practical to include the macro in the same template, especially you want to use this macro in other templates in your site. To centralize our macros, we can put them in their own template and import it.

Let’s put the socialList macro in a template called _macros.html (or _macros.twig), removing it from the previous template.

To include that template and get access to the macro, we need to import the _macros.html file in the template where we want to access the macro.

{% import '_macros' as siteMacros %}

We import it into the siteMacros variable so we have it handy and ready to use.

In our template, we can drop the _self prefix and instead call it like this:

{{ siteMacros.socialList(networks, "three-share") }}

And now not only do we have a macro that will generate a list of social networks for us, we also have it abstracted out into its own macros template so we can use it in any of our templates.

Ready to learn more about the Craft CMS?

My Craft Starter Pack is 4 ½ hours of premium learning that will get you started building sites with Craft for yourself, your company, or your clients.

Get Immediate Access

Filed Under: Craft CMS, Twig