Twig is the templating language used by Craft CMS to render web pages. We use Twig every day to do things like:
- List recent blog posts
- Output dynamic content
- Output forms or features from popular Craft plugins
- And create helpful publishing hints inside the control panel
While Twig is remarkably robust on its own, Craft extends it further with added filters, functions, and tags, making it even more powerful. We’re regularly delighted by just how easy it is to build templates with Twig in Craft.
Our Engineering Team has compiled this list of “TwigBits” that we reference often. If you are new to templating in Craft, we hope you find a tidbit or two that you can use as well. Enjoy!
Reading Craft's Config Settings
All of Craft's environment variables and General Config Settings can be easily accessed inside a Twig template. You can reference these values to check the environment your site is running in, display content conditionally based on a config setting, or leverage a custom config item in your Twig code.
To access these settings, use the {{ getEnv() }} function and the {{ craft.app.config.general }} service. Here are a few examples:
Craft 4 custom config settings are placed in a separate file, while in Craft 3 they can be added alongside the general config settings. You may also want to check out the new fluent config syntax available in Craft 4.2+.
Global Variables and Services
These are a few of the global variables and services we reference literally dozens of times when building a Craft site.
{{ siteUrl }} variable/function and {{ siteName }} variable
As it says on the tin, the siteUrl variable outputs the url of the current site. But note that there is also a siteUrl function as well. Along with the {{ siteName }} variable, you could write the following:
The {{ currentSite }} object and {{ craft.app.sites }} service
We often use Craft CMS to power multiple websites from a single installation. In that context, it's convenient to access information about both the current site and any other sites via the sites service.
Multi-sites in Craft CMS is a topic unto itself, but it's worth noting a couple things here:
- Each installation of Craft has only one Primary Site that serves as the default.
- Site Groups are generally used for separate entities (ex. separate site groups for "ABC Widget Co." and the "Widget Co Foundation").
- While Sites are used for localizations (translations) of the same entity within a Site Group.
So, for example, in a Site Group called "Widget Co Foundation" you may have three sites including Widget Co Foundation English, Widget Co Foundation Spanish, and Widget Co Foundation German.
The {{ craft.app.request }} object
Segments of the current url, GET / POST data, and more can be accessed with the request object.
Manipulating HTML
These functions and tags streamline HTML output, making it easy to create elements and set attribute values:
{{ tag() }}
The tag function is super convenient for outputting an element and its attributes using object-style syntax. It can even be used for custom HTML elements.
It's also possible to use opening and closing "tag" tags, making it easy to customize the html inside the element you are creating.
{{ attr() }}
With this function (and corresponding filter) you can compose an element's attributes with object-style syntax while outputting the tag itself manually. Another benefit of using this function versus creating attributes manually is that characters in attribute values, such as "&", will be HTML-encoded for you automatically.
{{ url() }}
The url function lets you avoid hard-coding domains or links into your templates. It is essentially the same as the siteUrl function mentioned previously, but it can also be used to generate urls to sites other than just yours. If you require a trailing slash at the end of every url for SEO purposes, this function will respect Craft's setting for that as well.
The {% html %}, {% css %}, and {% js %} tags
These three similar tags can be used to add arbitrary scripts, styles, and html code to specific places in your template. Whether you need to add a style tag in the head or include a modal element just before the closing body tag, these tags are your best friends.
Functions for Working with Images
We've seen how image tags can be created using the tag() function already, plus these two functions provide a convenient way to work with svgs and data urls.
{{ svg() }}
This function outputs svg code directly into your template. See Craft's documentation for the parameters and additional examples; it's very versatile.
{{ dataurl() }}
This function allows you to embed tiny images inline in the document. Most commonly, this would be used for small icons or css background images.
Frequent Filters
Filters are used to modify variables—think tasks like formatting a date or trimming the white space from the ends of a string. Both Twig core and Craft offer a stack of useful filters. It would be worth your time to familiarize yourself with all of them, but here are a few of our favorites:
{{ ...|default() }}
To output default text when a variable is not defined or empty.
{{ ...|date() }} and {{ ...|date_modify() }}
To format and modify dates.
{{ ...|join() }}
To combine an array of items into a string. We use this frequently to make our class lists easy to digest at a glance. (P.S. as you can see, we also love Tailwind CSS.)
{{ ...|filter() }} and {{ ...|group() }}
To work with arrays and objects. We use Matrix fields and the Neo plugin on most projects and we leverage these two filters to control their output.
{{...|escape() }}
To escape characters in HTML. If you are not using the attr() function mentioned earlier, you can escape special characters in attribute values with this filter.
Templating Tips
Here are a few "Did you know Twig can...?" tips that will help you create clean, DRY (Don't Repeat Yourself) templates.
You can interpolate strings.
Yes, you can interpolate strings in Twig! So instead of concatenating with the tilde character "~", you could do the following:
For loops can have an {% else %} statement.
Who knew!
You can use {% switch %}{% case %} in place of {% if %}{% else %}.
Craft adds this flow control that doesn't exist natively in Twig.
You can {% set %} a chunk of HTML.
This is a great way to keep your conditionals DRY.
You can call a parent block from a child block.
When overriding a block, it's possible to render the contents of the parent block by using Twig's built-in parent() function. (Template inheritance is powerful.)
You can preserve defaults and merge parameters with your includes.
This works for nested arrays and object (hashes) too by adding true as the recursive param (see Craft's docs for merge). Credit goes to Andrew Welch for this tip.
Utilities for Debugging
In development, you will want to inspect some data, see what the value of a variable is, or output an array to view the items it contains—think print_r in PHP or console.log in JS. In Twig we accomplish this with dd and dump.
{% dd() %}
The dd tag is added by Craft; and, it literally means "dump and die." This tag will output a variable to the screen and stop further execution.
{{ dump() }}
The dump function is part of Twig core. It's not as heavy-handed as Craft's dd, and simply outputs a variable inline in your HTML and continues executing the template.
Be sure to enable Craft's devMode config setting to enable dd and dump. While we're speaking of debugging, check out the Template Comments plugin by Andrew Welch. It makes it easy to track down which template file content originated from.
That's it, you've reached the end of our quick reference list of "TwigBits." We hope you found at least one helpful snippet in the mix. Did we miss one of your favorite bits of Twig? Let us know, and we may add it to the list.