How to use variables in Twig filter 'replace' - variables

Handing over an array from php of form
$repl_arr = array('serach-string1' => 'replace1', ...)
to a Twig template I would like to replace strings in a Twig variable per replace filter similar to this:
{{ block | replace({ repl_arr }) }}
That does not function and neither a variable loop like
{% for key,item in repla_arr %}
{% set var = block | replace({ key : item }) %}
{% endfor %}
does. What is wrong with it? How could it work?

Either you pass the whole array, or you loop the replaces.
But when looping the replaces you need to wrap key and value in parentheses to force interpolation of those
{% set replaces = {
'{site}' : '{stackoverflow}',
'{date}' : "NOW"|date('d-m-Y'),
} %}
{% set haystack = '{site} foobar {site} {date} bar' %}
{{ haystack | replace(replaces) }}
{% set output = haystack %}
{% for key, value in replaces %}
{% set output = output|replace({(key) : (value),}) %}
{% endfor %}
{{ output }}
fiddle

Related

DBT - how can i add model configuration (using a macro on {{this}}) in dbt_project.yml

I want to add node_color to all of my dbt models based on my filename prefix to make it easier to navigate through my dbt documentation :
fact_ => red
base__ => black.
To do so i have a macro that works well :
{% macro get_model_color(model) %}
{% set default_color = 'blue' %}
{% set ns = namespace(model_color=default_color) %}
{% set dict_patterns = {"base__[a-z0-9_]+" : "black", "ref_[a-z0-9_]+" : "yellow", "fact_[a-z0-9_]+" : "red"} %}
{% set re = modules.re %}
{% for pattern, color in dict_patterns.items() %}
{% set is_match = re.match(pattern, model.identifier, re.IGNORECASE) %}
{% if is_match %}
{% set ns.model_color = color %}
{% endif %}
{% endfor %}
{{ return({'node_color': ns.model_color}) }}
{% endmacro %}
And i call it in my model .sql :
{{config(
materialized = 'table',
tags=['daily'],
docs=get_model_color(this),
)}}
This works well but force me to add this line of code in all my models (and in all the new ones).
Is there a way i can define it in my dbt_project.yml to make it available to all my models automatically?
I have tried many things like the config jinja function or this kind of code in dbt_project.yml
+docs:
node_color: "{{ get_model_color(this) }}"
returning Could not render {{ get_model_color(this) }}: 'get_model_color' is undefined
But nothing seems to work
Any idea? Thanks

Replace Filter - How to pass a variable for the string to be replaced?

I am currently working on a symfony 6 project and try to pass a variable into a replace filter from Twig. However that does not work for me.
I tried it like this:
{% if form.vars.data.fileName|default %}
{% set system_type_short = get_env("SYSTEM_TYPE_SHORT") %}
{% set replaces = '/var/www/' ~ system_type_short ~ '.domain.de/public/uploads/images/' %}
{% set url = 'uploads/images/' ~ form.vars.data.fileName|replace({(replaces): ('')}) %}
<img src="{{ asset(url) }}" height="100"><br><br>
{% endif %}
The error I get:
A hash key must be followed by a colon (:). Unexpected token "punctuation" of value "{" ("punctuation" expected with value ":").
Can anyone tell me what I am doing wrong or how to pass a variable into the filter function "replace"?
You cannot use the variable syntax ({{ }}) when already in a twig expression.
So you just have to fix {{system_type_short}} and use string concatenation ~ instead.
You would get:
{% if form.vars.data.fileName|default %}
{% set system_type_short = get_env("SYSTEM_TYPE_SHORT") %}
{% set url = 'uploads/images/' ~ form.vars.data.fileName|replace({('/var/www/' ~ system_type_short ~ '.domain.de/public/uploads/images/'): ''}) %}
<img src="{{ asset(url) }}" height="100"><br><br>
{% endif %}

Variable alias in a for cycle with Jinja2

I have this code inside my html:
{% for macchine in range(20) %}
{% set macchina_usata = 'M'+ macchine|string %}
{{ data['macchina_usata'] }}
{% if data['macchina_usata'] is defined %}
do something..
{% endif %}
{% endfor %}
before it was without the for cycle, I just had to check if a variable is defined and I got the result, but now I want to put it in a Cycle for because I have to check 20 or more variables.
The variables that I got from the previous html are like M1, M2, M3, ... M20 then I thought that was a good idea to create a varible macchina_usata composed by M+ the int macchine converted in a string, but when I try to print it nothing happen, so, i guess that I'm using the Alias in a wrong way
You're using the literal string 'macchina_usata' as an index for data. You should instead use variable macchina_usata, without the quotes:
{{ data[macchina_usata] }}
{% if data[macchina_usata] is defined %}

specify variable array index for liquid

My liquid code is
{% assign _product_id = product.id %}
{% assign _product_tag = product.collections[0].title}
{% assign _product_name = product.title %}
{{_product_tag}}
{% assign pagla_array = collections[_product_tag].products %}
{{ pagla_array.first.title }}
Here last line showing nothing. if I use a static index for assigning pagla_array like {% assign pagla_array = collections['Beans'].products %} then it show value. What wrong did I make here?
This line:
{% assign _product_tag = product.collections[0].title}
Is not closed correctly. It should end with %}
In addition you should use handles for the collections, not title.
So it should become:
{% assign _product_tag = product.collections[0].handle %}
....
{% assign pagla_array = collections[_product_tag].products %}

Assign a value to array by index in Liquid

I am inside of a bit complex loops and I need to assign a value to an array by index, so that if the value is already there it will replace it, if not it will create it.
So I need to do something like this:
{% assign arr = '' | split: '' %}
{% assign arr[index] = value %}
which is not working, the array is still empty.
Is there any workaround to do this?
There is no direct workaround.
You can always re-create the array with a default value though that would only give you a single value.
One potential work around would be to re-create the source and fill in any missing defaults then re-split into an array
{% assign arr = someValue | split: '' %} <!-- splitting to single chars ? -->
{% assign withDefaults = '' %}
{% for ...%}
{% unless arr[loop.index0] == true %}
{% withDefaults = withDefaults | append : 'defaultValue,' %}
{% else %}
{% withDefaults = withDefaults | append : arr[loop.index0] | append : ',' %}
{% endfor %}
{% assign arr = withDefaults | split: ',' %} <!-- you'll have an extra blank element but that may not matter -->