Macros in Twig Templates

Last updated on
20 July 2022

This documentation needs work. See "Help improve this page" in the sidebar.

From the official Twig documentation: "Macros are comparable with functions in regular programming languages. They are useful to put often used HTML idioms into reusable elements to not repeat yourself."

{% macro input(name, value, type, size) %}
  <input type="{{ type|default('text') }}" name="{{ name }}" value="{{ value|e }}" size="{{ size|default(20) }}" />
{% endmacro %}

Macros differ from native PHP functions in a few ways:

  • Default argument values are defined by using the default filter in the macro body;
  • Arguments of a macro are always optional.
  • If extra positional arguments are passed to a macro, they end up in the special varargs variable as a list of values.

But as with PHP functions, macros don't have access to the current template variables. You can pass the whole context as an argument by using the special _context variable.

Calling the Macro

From _self

It's possible to place the macro within the same twig from which you call it. The _self context is used in this case...

{{ _self.input(name, value, type, size) }}


From External File

However, it's best practice to place macro(s) in a separate file (e.g., macros.twig) so that macro(s) can be used in more than one template.

For example, in a custom theme called "mytheme", we place the macros file here...

[site_root]/themes/custom/mytheme/templates/macros.twig

Note: the macros file can be named anything.twig, but cannot have the 'html' extension (i.e., macros.html.twig will not work). The file must also be placed in the "templates" directory regardless of where it is being used (i.e. for Layout Builder layouts that you've placed into .../mytheme/layouts, the macro must exist in ../mytheme/templates).

In the template where you want to use the macro, add this import statement.

{% import '@mytheme/macros.twig' as myMacros %}

The @mytheme magically locates your theme's "templates" directory but you must define any further directory structure in your import statement, as in:

{% import '@mytheme/foo/bar/macros.twig' as myMacros %}

Note that older versions of this documentation stated that defining the nested directory structure wasn't needed, so ymmv. If you're doing this in a custom module, use the same technique, just use the module name instead of the theme name (e.g., @mycustommodule).

Then to use the macro...

{{ myMacros.input(name, value, type, size) }}

Examples 

In Drupal 8+, a macro is used to create, for example, the main navigation (see menu.html.twig).

Help improve this page

Page status: Needs work

You can: