Email templates: how to use conditionals like if/else?

Your software
My Mautic version is: 5.1.1 / GrapeJS
My PHP version is: 8.2
My Database type and version is: latest MySQL

Your problem
I cannot figure out how to use if/else conditionals.

Is there no support in Mautic for if/else conditionals?

I am sending some transactional emails from API, which pass some tokens. I’ve been able to display the token values from API with {name}, {username}, {siteUrl}, etc.

But I’ve tried various combinations of {% if value == 1 %} {% else %} using <mj-raw>, without <mj-raw>.

I also tried {% TWIG-BLOCKS %} plugin but that just blew up my Mautic server and I had to reinstall everything.

Some example code I tried:

<mj-text font-size="36px" align="center">
	{% TWIG_BLOCK %} 
		{% if is_gift == 1 %}
			<p>You received a gift!</p>
		{% elseif is_gift == 0 and conversationCount == 1 %}
			<p>New message from {user_1_displayName}</p>
		{% else %}
			<p>You have {messageCount} new messages</p>
		{% endif %}
	{% END_TWIG_BLOCK %}
</mj-text>
<mj-text font-size="36px" align="center">
	{% TWIG_BLOCK %} 
		{% if is_gift %}
			<p>You received a gift!</p>
		{% elseif not is_gift and conversationCount %}
			<p>New message from {user_1_displayName}</p>
		{% else %}
			<p>You have {messageCount} new messages</p>
		{% endif %}
	{% END_TWIG_BLOCK %}
</mj-text>
<mj-text font-size="36px" align="center">
	<mj-raw>
	<!--
		{% TWIG_BLOCK %} 
			{% if is_gift %}
				<p>You received a gift!</p>
			{% elseif not is_gift and conversationCount %}
				<p>New message from {user_1_displayName}</p>
			{% else %}
				<p>You have {messageCount} new messages</p>
			{% endif %}
		{% END_TWIG_BLOCK %}
	-->
	</mj-raw>
</mj-text>

So while I still had the MauticAdvancedTemplateBundle installed, this ALWAYS resulted in the ELSE condition.

Regardless of my API token value {is_gift} being 1, 0, “1”, “0” and the same for {conversationCount} of 1, 2, “1”, “2”.

Is there any way to get this working?

Do I need to be wrapping bits in <mj-raw> (and if so, which bits)?

I also tried {% set label = "This is a label" %} and couldn’t get that to display, it would always output the literal {label} instead of the value.

Any suggestions on how to get this basic code working?

Spent the last 8 hours on this and the documentation is non-existent on how to do this properly.

I found a way to get Twig working within GrapeJS.

It only requires one very small code change:

app\bundles\EmailBundle\Helper\MailHelper.php

After line 359, which is currently:

self::searchReplaceTokens($search, $replace, $this->message);

Add the following lines of code (starting at line 361):

// Custom Twig code handler in email template
$body = $this->message->getHtmlBody();
$isTemplateTwigCode = str_contains($body, '{%');

if ( $isTemplateTwigCode )
{
    if ( empty($this->twig) ) {
        $this->twig = $this->factory->getTwig();
    }

    // $tokens: revert key from "{var}" to "var"
    $cleanTokens = [];
    foreach ( $tokens as $key => $value )
    {
        $key = str_replace(['{', '}'], '', $key);
        $cleanTokens[$key] = $value;
    }

    // execute twig logic and update email body with results
    $body = $this->twig->createTemplate($body)->render($cleanTokens);
    $this->message->html($body);
}

Then just upload and overwrite the existing file of the same name on your server, I didn’t even need to clear cache (from what I remember).

Now when you go into GrapeJS, you can use Twig code directly with API token variables, ie.:

<mj-raw>
    {% if countMessages == 1 %}
        You have one new message from {messageUsername}.
    {% endif %}
</mj-raw>

Or like this:

<mj-raw>{% if countMessages == 1 %}</mj-raw>
You have one new message from {messageUsername}.
<mj-raw>{% endif %}</mj-raw>

Warning: GrapeJS will convert < and > to &lt; and &gt;. So in these situations, you need to add comment blocks around your code to prevent it from being replaced, like this:

<mj-raw><!-- {% if countMessages > 1 %} --></mj-raw>
You have {countMessages} new messages
<mj-raw>{% endif %}</mj-raw>

Notice how you only need to put <!-- ... --> when there is a > or < comparison operator.

I haven’t tried {% for ... %} or {% let var = "some text" %}, but feel free to try it and let me know how it goes. It uses the Twig library so it should have support for all of those.

By the way, the method behind this is – the place where you are adding this code, the email template was already converted from MJML to HTML.

This means that, by the time this new piece of code is executed, placeholder global variables and contact variables were already interpolated.

So for inserting token, both of these will work:

{ var }
{{ var }}

And if you need to do transformations (the domain of Twig), use the {{ ... }} instead, like so:

{{ var ?? "Default Value" }}
{{ var ?? 0 }}

In this example, the code will set a default value if the token var was missing or empty.

But doing this wouldn’t work: { var ?? "Default Value }. Need to be double moustaches.

This topic was automatically closed 36 hours after the last reply. New replies are no longer allowed.