How not to escape path() in Twig Template - twig

My objective is to render a Twig Template and send the resulting HTML via API to Mailchimp to be sent out.
My current process:
1) create a Twig-Template email.html.twig.
2) $html = $this->renderView('MyBundle:email.html.twig');
3) sendHtmlViaApi($html);
The issue:
I need a URL to contain a Mailchimp Merge Tag String, which has to be *|VARIABLE|*. I do that with {{ path('my_route', {variable : '*|VARIABLE|*'}) }}. The desired result: /myroute/*|VARIABLE|*. The result I get: /myroute/*%7CVARIABLE%7C*.
Already tried and failed methods:
1) using {% autoescape %}
2) |raw
3) Twig Extension with new url_decode Filter from Symfony2 Twig stop escaping path

So you want Twig to stop the automatic URL encoding.
You can pass a placeholder with only letters and underscore to path(), so that it won't be escaped. Then you can replace the placeholder with the string Mailchimp expect:
{{ path('my_route', {variable : 'MAILCHIMP_VARIABLE'})|replace({
'MAILCHIMP_VARIABLE': '*|VARIABLE|*'
}) }}

Thanks for your suggestions!
In the end it was all my own fault... One of the merge tags was missing on the mailchimp-side setup, so it couldn't replace it with the desired value.
Silly me!

Related

If twig replace isnt called, replace by nothing

I want to give my users control over an input field via twig replace. So I created a var
<input type='text' %attr%>
Now with twig:
{{ var | replace({"%attr%":"id='12'"}) | raw}}
But if my users dont use replace, I dont want to display %attr% in the input field.
Is there a native twig way to do this?
As already commented, this is a bad design and it would be better to rethink your strategy. Anyhow a possible solution would be to write a custom filter and use that one over the raw filter.
By adding the option is_safe to the filter, the filter will behave exactly like raw, but you have more control over the end result.
In this case, you could replace %attr% if it hasn't been replaced by the filter replace before. You could even extend this list if needed be
$twig->addFilter(new \Twig\TwigFilter('safe', function($val) {
return str_replace([
'%attr%',
],[
'',
], $val);
}, ['is_safe' => ['html']]);
After you've added the filter to twig, you can use this filter anywhere:
{{ var | replace({"%attr%":"id='12'"}) | safe }}
{{ var | safe }}

How to define "ends with any two letters after underscore" in Twig

In the following example, this condition includes all type elements of an array that do not include _.
{% for type in array %}
{% if '_' not in type) %}
Instead, I would like to include all elements that do not end with _any2letters, where "any2letters" is actual any 2 letters. I examined Twig documentation and wasn't able to find the required syntax.
It was solved using:
{% if not (type matches '/_[a-z]{2}$/') %}
This solution takes advantage of PHP regex syntax.
"/" are used in Twig to define borders of regular expressions.
"_" is my underscore as is; [a-z]{2} means "2 lowercase letters".
And finally $ means that the preceding symbols are in the end of the
string.

Twig RAW filter on literal string not working

{{ (vendorData.description) ? vendorData.description : "<em>No Description Entered</em>"|raw }}
When the value is not present I see:
<em>No Description Entered</em>
Printed literally on the screen in the web browser.
Raw should force the characters to be literal, not > < etc.
Why does this not work on a "created string" but if I do it on a string variable it works?
You need to place brackets around the whole statement like so:
{{ ((vendorData)
? vendorData
: "<em>No Description Entered</em>")|raw }}
Here is a working twigfiddle to show it working:
https://twigfiddle.com/fs2oc2
You can use twigfiddle to experiment with your code.
From feedback in comments section:
here is a twig example to show what you need: https://twigfiddle.com/hjyslr

In Twig, how do I use a dynamic key when translating

In my translation yml file I have these translations setup
pages:
training_missions:
...
application_name:
admin: "Admin Website"
mobile: "Mobile App"
kiosk: "Kiosk"
In my twig file, I need to set the application_name dynamically, but I can't get it to work properly.
This will translate fine, it gives me "Mobile App"
{{ 'pages.training_missions.application_name.mobile' | trans()}}
But this doesn't work, it gives me "pages.training_missions.application_name.mobile"
{{ 'pages.training_missions.application_name.'~trainingMission.application | trans() }}
edit:
The variable trainingMission.application contains one of the 3 strings I put in the yaml file : admin, mobile, kiosk
edit 2:
The solution is to wrap the string in parenthesis as per #Matteo 'Ingannatore' G. comment
It is possible! Use round brackets like this:
{{ ('pages.training_missions.application_name.'~trainingMission.application) | trans() }}
Use array accessor syntax:
{{ pages[training_missions].application_name.mobile }}

How to create a multiline string variable in swig template?

I'm trying to create a multiline string variable in swig :
{% set myVariable = "
multi
line
string
" %}
Then I log it :
{% logMyVariable(myVariable) %}
But I don't understand why my variable is not displayed on several lines :
multi line string
Whereas I was expecting :
multi
line
string
Do you know how I could do that?
In HTML, new lines in text aren’t rendered when the text is displayed. For example, this HTML:
<p>Let’s split this sentence up
onto
multiple
lines.</p>
Will render like this:
Let’s split this sentence up onto multiple lines.
You might want to wrap your log in a <pre> tag, as that will preserve new lines (and multiple spaces between words, which are also ignored in rendered HTML):
<pre>{% logMyVariable(myVariable) %}</pre>

Resources