Navigation
Twig Templates
Compatible with Mautic 4, 5, 6, and 7.
Learn how to leverage Twig templates for customizing your Mautic experience. Twig provides a powerful yet simple syntax for adding logic directly into your Mautic assets.
Basic Example: Personalized Greeting
{% if contact.firstname %}
<p>Hello {{ contact.firstname }}!</p>
{% else %}
<p>Hello there!</p>
{% endif %}
{# More concise using the 'default' filter #}
<p>Welcome, {{ contact.firstname|default('Valued Customer') }}!</p>
Reusing Twig Templates
Insert one saved Twig Template within another using {twigtemplate=TEMPLATE_NAME}:
{% if contact.membership_tier == 'gold' %}
{twigtemplate=Gold Member Offer}
{% elseif contact.membership_tier == 'silver' %}
{twigtemplate=Silver Member Offer}
{% else %}
{twigtemplate=Standard Welcome Offer}
{% endif %}
Dynamic Template Names
Use Twig tokens inside the template name for dynamic selection:
{twigtemplate=offer-{{ contact.membership_tier|default('standard') }}}
Installation
Step 1: Copy the plugin
Place the plugin folder in plugins/MauticTwigTemplatesBundle
Step 2: Clear cache
php bin/console cache:clear
Step 3: Reload plugins list
php bin/console mautic:plugins:reload
Step 4: Re-generate assets
php bin/console mautic:assets:generate
After installation, go to Settings > Plugins in Mautic and make sure the plugin is enabled.
Available Tokens
Contact Object (contact)
Access any contact field using its alias:
Hello {{ contact.firstname|default('there') }}!
Your email is {{ contact.email }}.
- Custom Fields:
contact.custom_field_alias - Tags:
contact.tags(array — use{% for tag in contact.tags %}) - Segments:
contact.segments(array withidandnameproperties) - Companies:
contact.companies(all companies as array) - Primary Company:
contact.primaryCompany(primary company object, or first if none marked primary)
{% if contact.primaryCompany %}
<p>{{ contact.primaryCompany.companyname }}</p>
<p>{{ contact.primaryCompany.companyindustry|default('Not specified') }}</p>
{% endif %}
Form Result Tokens
formresult— Most recent form submission data (works when email is triggered by form action)formresults— Array of all submissions for the triggering form
Thank you, {{ formresult.firstname }}! Your message: {{ formresult.message_field }}
Functions
getFormResults(formId, contactId, limit, page, orderBy, orderDirection)— Fetch form submissions for any form by IDgetFormResultsCount(formId, contactId)— Count submissions for a formalreadySubmitted(formId, contactId)— Returnstruewhen the contact already submitted the form
{% set count = getFormResultsCount(12, contact.id) %}
<p>You have submitted this form {{ count }} time(s).</p>
Hiding a form from contacts who already submitted it
alreadySubmitted(formId, contactId) returns a boolean. Leave contactId out and the currently tracked contact is used, resolved from the Mautic tracking cookie:
{% if alreadySubmitted(formId=123) %}
<p>You have already registered. The form is no longer available for you.</p>
{% else %}
{form=123}
{% endif %}
Pass a contact explicitly when you already have one:
{% if alreadySubmitted(123, contact.id) %}
<p>This contact already submitted Form 123.</p>
{% endif %}
Available in emails, SMS and landing pages. Two limitations worth knowing: it only hides the form in the UI and does not prevent a server-side double submit, and it returns false when no contact can be identified — an anonymous visitor without a tracking cookie still sees the form.
Email Tokens (tokens)
When sending emails via API, pass custom tokens in the payload:
Your special code is: {{ tokens['{discount_code}']|default('No code available') }}
Snippets
Access Primary Company Details
{% if contact.primaryCompany %}
<p>{{ contact.primaryCompany.companyname }}</p>
<p>Industry: {{ contact.primaryCompany.companyindustry|default('Not specified') }}</p>
{% endif %}
List All Companies
{% for company in contact.companies %}
<li>{{ company.companyname }}{% if company.is_primary == '1' %} (Primary){% endif %}</li>
{% endfor %}
Contact's Tags
{% for tag in contact.tags %}<li>{{ tag }}</li>{% endfor %}
Get Content from External URL
{% set product_data = 'https://api.yourstore.com/products/1' | get_content_from_url | json_decode %}
{% if product_data %}<p>{{ product_data.name }} — {{ product_data.price }}</p>{% endif %}
Content Segmentation
{% if contact.affinity == 'b2b' %}
<p>B2B Content</p>
{% else %}
<p>General Content</p>
{% endif %}
Time-Based Greetings
{% set currentHour = "now"|date("H") %}
{% if currentHour >= 5 and currentHour < 12 %}
<p>Good morning, {{ contact.firstname|default('there') }}!</p>
{% elseif currentHour >= 12 and currentHour < 18 %}
<p>Good afternoon, {{ contact.firstname|default('there') }}!</p>
{% else %}
<p>Good evening, {{ contact.firstname|default('there') }}!</p>
{% endif %}
Fallback Values
<p>Welcome, {{ contact.firstname|default('Valued Customer') }}!</p>
Date Magic
Tomorrow is {{ "now"|date_modify('+1 day')|date("l, F jS, Y") }}
Today's date: {{ "now"|date("Y-m-d") }}
Random Selection
<p>{{ random(['Hello', 'Hi', 'Hey there']) }}, {{ contact.firstname|default('friend') }}!</p>
JSON Decode (Cart Data)
{% set cart = contact.cart_data | json_decode %}
{% if cart and cart.items is not empty %}
{% for item in cart.items %}
<li>{{ item.name }} — {{ item.price }}</li>
{% endfor %}
{% endif %}
RSS Feed
{% set feed = 'https://your.rss.feed.url' | rss %}
{% for item in feed.channel.item %}
<li><a href="{{ item.link }}">{{ item.title }}</a></li>
{% endfor %}
Forms Support
You can use data that contacts submit through Mautic forms directly in your Twig Templates.
{{ formresult }}— Most recent form submission (works when email triggered by form){{ formresults }}— All submissions for the triggering formgetFormResults(formId, contactId, limit, page, orderBy, orderDirection)— Fetch any form's submissionsgetFormResultsCount(formId, contactId)— Count submissions
Example: Display Recent Submissions
{% set results = getFormResults(12, contact.id, 3) %}
{% for submission in results %}
<tr>
<td>{{ submission.dateSubmitted|date('M j, Y') }}</td>
<td>{{ submission.firstname }}</td>
<td>{{ submission.email }}</td>
</tr>
{% endfor %}
Example: Registration Cap
{% set totalRegistrations = getFormResultsCount(3) %}
{% if totalRegistrations >= 10 %}
<p>Registration is now closed.</p>
{% else %}
{form=3}
{% endif %}
Focus Support
Use Twig Templates inside Mautic Focus Items (popups, bars, notifications) to show personalized content.
Insert {twigtemplate=...} in the content of your Focus Item. The template will be rendered using the current contact's data, and trackable URLs will be processed for Focus Item tracking.
{% if contact.points > 100 %}
{twigtemplate=special_offer}
{% else %}
{twigtemplate=latest_news}
{% endif %}
- If the visitor is known (identified by Mautic tracking), their contact data is used.
- If unknown, your template's default values or fallback logic will be used.
Custom Objects
Note: Requires the MauticCustomObjectsBundle plugin installed and active.
Use the getCustomObjectItems function to fetch data from a Custom Object:
getCustomObjectItems(alias, limit, page, orderBy, orderDirection, search, contactId)
Example: Show Recent Changelog Entries
{% set changelogs = getCustomObjectItems('changelogs', 5, 1, 'name', 'DESC') %}
{% for item in changelogs %}
<h3>{{ item.name }}</h3>
<div>{{ item.fields.content_alias | raw }}</div>
{% endfor %}
Example: Contact's Last Order
{% set lastOrder = getCustomObjectItems('orders', 1, 1, 'id', 'DESC', null, contact.id) %}
{% if lastOrder is not empty %}
{% set order = lastOrder|first %}
<p>Last order: #{{ order.name }} on {{ order.fields.date_ordered_alias }}</p>
{% endif %}
Embedding Externally
You can embed Mautic Twig Templates on your own website or share them via a direct link.
Embed with JavaScript
Paste this where you want the content on your page:
<script async defer type="text/javascript"
src="https://your-mautic.com/twig/template/{TEMPLATE_ID}/{UNIQUE_HASH}.js"></script>
Personalization is based on the visitor's Mautic tracking cookie.
Use Direct Link
Get a unique URL that displays the rendered template as a standalone HTML page — useful for previewing, iframes, or sharing:
https://your-mautic.com/twig/template/{TEMPLATE_ID}/{UNIQUE_HASH}.html
Replace
your-mautic.com,{TEMPLATE_ID}, and{UNIQUE_HASH}with values from Mautic for your specific template.
API
The Twig Templates plugin extends the Mautic API for managing templates programmatically.
Note: Ensure API access is enabled in your Mautic settings and you have the necessary permissions for
twigtemplates.
GET /api/twigTemplates
List all Twig Templates.
{ "twigTemplates": [{ "id": 1, "name": "Welcome Email Snippet", "template": "Hello {{ contact.firstname|default('there') }}!" }] }
GET /api/twigTemplates/{templateId}
Get a specific template by ID.
POST /api/twigTemplates/new
Create a new template.
{
"name": "Dynamic Footer",
"template": "<p>Copyright {{ 'now'|date('Y') }}</p>",
"description": "Shows the current year in the footer"
}
PATCH /api/twigTemplates/{templateId}/edit
Update an existing template. Send only the fields you want to change.
DELETE /api/twigTemplates/{templateId}/delete
Permanently remove a template.