Access variable inside a loop and variable in Twig - twig

I would like to do the following:
{% for i in 0..10 %}
{% if content_{{ i }}_raw == 2 %}
...
{% endif %}
{% endfor %}
Is it possible to get {{ i }} inside the variable content_1_raw and replace the 1 with the value of i?

Yes. The _context variable holds all variables in the current context. You can access its values with the bracket notation or using the attribute function:
{% for i in 0..10 %}
{% if _context['content_' ~ i ~ '_raw'] == 2 %}
...
{% endif %}
{# or #}
{% if attribute(_context, 'content_' ~ i ~ '_raw') == 2 %}
...
{% endif %}
{% endfor %}
I have written more details about this here: Symfony2 - How to access dynamic variable names in twig
Also, instead of writing 'content_' ~ i ~ '_raw' (tilde, ~, is string concatenation operator), you can also use string interpolation:
"content_#{i}_raw"

Related

How to render HTML to a variable

I need to render a list of HTML elements with content and put it into a variable. How can I do this efficient in twig?
e.g. I need to render the post tracking URLs from an order which can have several shippings / parcels.
{% for delivery in order.deliveries %}
{% for trackingCode in delivery.getTrackingCodes() %}
{{ trackingCode }}<br/>
{% endfor %}
{% endfor %}
Instead of printing this directly into the output I like first to put this rendered output into a variable like
{% set output = ... %}
...
{{ output }}
How can I do this in twig?
Just the concatenate the html to the output variable. Keep in mind you'll need to define to the variable outside the for-loop in order to use it outside the loop.
{% set foo = '' %}
{% for i in 1..10 %}
{% set foo = foo ~ ''~i~'' %}
{% endfor %}
{{ foo|raw }}
demo
After long search I found a better more efficient way
you can use {% set var %} with {% endset %} as a whole output block. Means the whole output will be set to the variable. This makes the life much easier and readable.
e.g.
{% set trackingText %}
{% for delivery in order.deliveries %}
{% for trackingCode in delivery.getTrackingCodes() %}
{{ trackingCode }}<br/>
{% endfor %}
{% endfor %}
{% endset %}
...
{% if trackingText|trim is not empty %}
You can track the delivery by using the following URL:<br/>
{{ trackingText }}
<br/>
{% endif %}

Twig strip textarea and create array

I'm trying to strip some text from a value and afterwards create an array from it with the stripped values.
I'm having troubles to strip the text value.
I can only do this on the frontend since I have no access to the backend (SaaS platform)
In below example value.value (originally a textarea) returns the following text:
[185047078]1x something - Type 1
[415533322]1x something - something
[152890667]1x something 500x500 mm
I want to strip the text so I have [185047078], [415533322], [152890667] left or without the brackets.
Normally in JS you would do something like:
hide_ids = txt.match(/[^\]\[]+(?=\])/g)
However it need to be done in Twig.
Afterwards I want to push the values into an array hide_ids.
{% set hide_ids = [] %}
{% if product.custom %}
{% for custom in product.custom %}
{% if 'Some title' in custom.title %}
{% for value in custom.values %}
{% set hide_this_id = value.value %}
{% if hide_this_id matches '{/[^\]\[]+(?=\])/g}' %}
{% set hide_ids = hide_ids | merge([hide_this_id]) %}
{% endif %}
{% endfor %}
{% endif %}
{% endfor %}
{% endif %}
{% set hidden = false %}
{% if id in hide_ids %}
{% set hidden = true %}
{% endif %}
What is the equivalent of match in Twig? I also tried replace but I just can't get that text stripped.
Any help greatly appreciated!
You could go with some simple string functions.
{% for id in ids %}
{{ id | split(']', 2)[0] | replace({'[': '',}) }}
{% endfor %}
demo
split is the explode of twig. This will separate your string in chased based on the ] character. The 2nd parameter (2) ensures there will only be maximum 2 parts in the array.
replace is just str_replace
If you wanted to solve this with regex you would either need to write a function/filter with preg_match or install an extension like this

Twig replace part of string with chosen character

I want to replace part of string characters with asterisks in Twig.
For example:
SomePartlyVisibleStringHere
I want to change every letter after 4th in this string with asterisks, to have result like that:
Some*********************
Is it possible to do without defining new Twig helper?
You could make a macro (a function in Twig) and call it whenever you want to do this.
{% macro redact(topSecret) %}
{% set length = topSecret|length - 4 %}
{{ topSecret|slice(0, 3) }}{% for i in 0..length %}*{% endfor %}
{% endmacro %}
{# You have to import from _self if the macro is declared in the same file. #}
{% import _self as sharpie %}
{{ sharpie.redact('Top secret information') }}
{# => Top******************* #}
Example: https://twigfiddle.com/aobt8s
This worked for me:
{% set string = 'SomePartlyVisibleStringHere' %}
{% set starCount = string|length - 4 %}
{{ string[:4] }}{% for i in 1..starCount %}*{% endfor %}
If you have to do it more than once I would suggest making a custom filter, then you can just do:
{% set string = 'SomePartlyVisibleStringHere' %}
{{ string|customFilterName }}

I want to genrate dynamic variable in TWIG and fetch value

i want to set dynamic variable and get value of that variable. I had pass "orderDetails" to my twig template.
$customerProfile = array(
'ns1' => $customerProfile->getNs1(),
'ns2' => $customerProfile->getNs2(),
'custId' => $customerProfile->getCustId()
)
return $this->render('PortalBundle::popup.html.twig', array(
'orderDetails' => $customerProfile
));
get that variable like {{orderDetails.ns1}}, {{orderDetails.ns2}} like this but i have 15 to 16 variable like this and i want to fetch this variable in loop.
i have code for this like
{% for i in 1..13 %}
{% set nsOrd = 'orderDetails.ns'~i %}
{% if nsOrd %}
{{nsOrd}}
{% endif %}
{% endfor %}
i want to fetch variable {{orderDetails.ns1}} and other. Give me your suggestion.
thanks Yoshi, I have hundered of variable in array. thanks for support, i have found and successfully get output using this.
{% for i in 1..13 %}
{% if orderDetails['ns' ~ i] is defined %}
{{orderDetails['ns' ~ i]}}
{% endif %}
{% endfor %}

Scope of variable in jinja2 template

I am writing jinja2 template based application. I am trying to write a logic to set variable.
{% set last_item = none %}
{% for u in users %}
{% if not u.username == user.username%}
{% if g.user.is_bestfriend(u) %}
{% set last_item = 'true' %}
{% endif %}
{% endif %}
{% endfor %}
{{last_item}}
but after {% endfor %}, last_item value is again set to none, instead of true. Is there any way to set it to true in jinja2 template?
Since version 2.10 you can do this using a namespace variable, set before entering the scope:
{% set ns = namespace(found=false) %}
{% for item in items %}
{% if item.check_something() %}
{% set ns.found = true %}
{% endif %}
* {{ item.title }}
{% endfor %}
Found item having something: {{ ns.found }}
See also the documentation: http://jinja.pocoo.org/docs/2.10/templates/#assignments
Due to scoping rules in jinja2, you cannot access a variable outside the scope that it was set in. Sorry :(

Resources