How can I reuse a block to make other ones? - twig

This is what i want (re-use a block for others in order not to code duplicates too much) :
{%- block distance_widget (block_a, block_b, block_c) -%}
{%- if unit -%}
<div class="input-group">
{{- block('form_widget_simple') -}}
<div class="input-group-append">
<span class="input-group-text">{{ unit|default('kg') }}</span>
</div>
</div>
{%- else -%}
{{- block('form_widget_simple') -}}
{%- endif -%}
{%- endblock distance_widget %}
or it may be done like that (i think extend cant be used within a block but maybe there is another methode that can do this) ?
{%- block_a -%}
{%- extends block distance_widget -%}
{%- enblock -%}
{%- block_b -%}
{%- extends block distance_widget -%}
{%- enblock -%}
{%- block_c -%}
{%- extends block distance_widget -%}
{%- enblock -%}
this is what i currently have... (a lot too much code duplicats, its ugly i want a clean code so i want to make a re-usable block) :
{%- block_a -%}
{%- if unit -%}
<div class="input-group">
{{- block('form_widget_simple') -}}
<div class="input-group-append">
<span class="input-group-text">{{ unit|default('kg') }}</span>
</div>
</div>
{%- else -%}
{{- block('form_widget_simple') -}}
{%- endif -%}
{%- enblock -%}
{%- block_b -%}
{%- if unit -%}
<div class="input-group">
{{- block('form_widget_simple') -}}
<div class="input-group-append">
<span class="input-group-text">{{ unit|default('kg') }}</span>
</div>
</div>
{%- else -%}
{{- block('form_widget_simple') -}}
{%- endif -%}
{%- enblock -%}
{%- block_c -%}
{%- if unit -%}
<div class="input-group">
{{- block('form_widget_simple') -}}
<div class="input-group-append">
<span class="input-group-text">{{ unit|default('kg') }}</span>
</div>
</div>
{%- else -%}
{{- block('form_widget_simple') -}}
{%- endif -%}
{%- enblock -%}

It does the trick (it allows to reuse the already defined blocks) :
{{- block('distance_widget') -}}

Related

how to remove line break in twig template containing a for loop and an include?

I would like to remove a line break between multiple html tags (<a>) from a twig template which contains a for loop and an include of another twig template.
{% for child in field.value %}
{% include '#EasyAdmin/crud/field/association_link.html.twig' with {
field: {
value: child,},
} %}
{%- if loop.index < field.value|length -%}
,
{%- endif %}
{% endfor %}
And the twig templated included :
{% set url = ea_url()
.setController('App\\Controller\\Admin\\' ~ get_class(field.value)|split('\\')|last ~ 'CrudController')
.setEntityId(field.value.id)
.setAction('edit') %}
{% if url -%}
{{ field.value|markdown }}
{%- else -%}
{{ field.value|markdown }}
{%- endif -%}
It renders such a result :
<a href=url2>name1<a/>
,
<a href=url2>name2<a/>
How to get this result instead ?
<a href=url2>name1<a/>,
<a href=url2>name2<a/>
2nd row, 6th field : a break line before and after the comma

Jinja2 template: output format

i am quite new to jinja2 template and i try to get output data by using jinja template.
data_list=
[
{
"v4-filter": {
"accept_1": [
{
"destination-prefix-list": "v4-future-prefix-list-1"
},
{
"source-prefix-list": "v4-future-prefix-list-2"
},
{
"source-prefix-list": "v4-future-prefix-list-3"
},
{
"destination-port": "80"
},
{
"destination-port": "443"
},
{
"action": "accept"
}
],
"accept_2": [
{
"destination-prefix-list": "v4-future-prefix-list4"
},
{
"source-prefix-list": "v4-future-prefix-list5"
},
{
"action": "accept"}]}}]
My jinja template
{%- for d in data_list -%}
{%- for k,v in d.items() -%}
{%- for term,value in v.items() -%}
term:: {{ term }}
{%- for dict_item in value -%}
{%- for key, value in dict_item.items() -%}
{% if key == "source-prefix-list" %}
source-address:: {{value}}
{% endif %}
{% if key == "destination-prefix-list" %}
destination-address:: {{value}}
{% endif %}
{% if key == "destination-port" %}
destination-port:: {{value}}
{% endif %}
{% if key == "action" %}
action:: {{value}}
{% endif %}
{%- endfor -%}
{%- endfor -%}
{%- endfor -%}
{%- endfor -%}
{%- endfor -%}
Output that i get
term:: accept_1
destination-address:: v4-future-prefix-list-1
source-address:: v4-future-prefix-list-2
source-address:: v4-future-prefix-list-3
destination-port:: 80
destination-port:: 443
action:: accept
term:: accept_2
destination-address:: v4-future-prefix-list4
source-address:: v4-future-prefix-list5
action:: accept
Output that i want
term accept_1 {
source-address:: v4-future-prefix-list-1
v4-future-prefix-list-2
v4-future-prefix-list-3
destination-port:: 80
443
action:: accept
}
term accept_2 {
source-address:: v4-future-prefix-list-5
destination-address:: v4-future-prefix-list-4
action:: accept
}
The jinja template looks not nice i know, but at the end it contains all the information that i need, is just question now to format properly as expected.
I tried by using nested if statement to properly reach the result but with no success.
Any hint is welcome.
Thanks, Pablo.
The following template will produce the requested output:
{%- for d in data_list -%}
{%- for k,v in d.items() -%}
{%- for term,value in v.items() -%}
{%- set label = namespace(source=false, dest=false, port=false) %}
term {{ term }} {
{%- for dict_item in value -%}
{%- for key, value in dict_item.items() -%}
{%- if key == "source-prefix-list" %}
{% if not label.source %}source-address::{% else %}{{ ' '*16 }}{% endif %} {{value}}
{%- set label.source = true %}
{%- endif %}
{%- if key == "destination-prefix-list" %}
{% if not label.dest %}destination-address::{% else %}{{ ' '*21 }}{% endif %} {{value}}
{%- set label.dest = true %}
{%- endif %}
{%- if key == "destination-port" %}
{% if not label.port %}destination-port::{% else %}{{ ' '*18 }}{% endif %} {{value}}
{%- set label.port = true %}
{%- endif %}
{%- if key == "action" %}
action:: {{value}}
{%- endif %}
{%- endfor %}
{%- endfor %}
}
{% endfor %}
{%- endfor %}
{%- endfor %}
Output:
term accept_1 {
destination-address:: v4-future-prefix-list-1
source-address:: v4-future-prefix-list-2
v4-future-prefix-list-3
destination-port:: 80
443
action:: accept
}
term accept_2 {
destination-address:: v4-future-prefix-list4
source-address:: v4-future-prefix-list5
action:: accept
}
Here we use a Jinja2 namespace object that we can use to track whether a label has been already printed or not in the current cycle. If a label is printed, we flip the boolean tracking variable in our label namespace variable and then just print enough space to correctly align the next printed value.

"block checkbox_widget" draw a checkbox

I'm customizing the checkbox_widget in one form. In the template that draw this form I have:
{%- block checkbox_widget -%}
{% set emailmult1a00 = app.session.get('emailmult1a00') %}
<input type="checkbox" name="{{ emailmult1a00 }}" />
{%- endblock checkbox_widget -%}
It works fine in my form, but it draws a checkbox in place where the block is in the template.
How can I delete this checkbox?
I resolve the problem using a separate Template:
{# templates/form/fields.html.twig #}
{%- block checkbox_widget -%}
{% set emailmult1a00 = app.session.get('emailmult1a00') %}
<input type="checkbox" name="{{ emailmult1a00 }}" />
{%- endblock checkbox_widget -%}
And then, in my form template:
{% form_theme formulario 'form/fields.html.twig' %}

Don't know what I am doing wrong in below code in twig for counter

Counter always printing 1
{% if label_hidden %}
{% if multiple %}
{% for item in items %}
{{ item.content }}
{% endfor %}
{% else %}
/* counter set below for incriment */
{% set counter = 1 %}
{% for item in items %}
{{ counter }}
/* condition check*/
{% if counter == 2 %}
<div class="spectra-promo col-md-6 spectra-offer-info">
<h3>{{ item.content }}</h3>
{% endif %}
/* condition check*/
{% if counter == 3 %}
<h5>{{ item.content }}</h5>
<div class="choose-offer">
<div class="left-sec">
{% endif %}
/* condition check*/
{% if counter == 4 %}
<p>{{ item.content }}</p>
<div class="right-sec">
<p><i class="fa fa-angle-right" aria- hidden="true"></i></p>
</div>
</div>
</div>
{% endif %}
/* counter increment below */
{% set counter = counter + 1 %}
{% endfor %}
{% endif %}
{% endif %}
Instead of creating a counter, you can directly use the loop variable:
{% if label_hidden %}
{% if multiple %}
{% for item in items %}
{{ item.content }}
{% endfor %}
{% else %}
{% for item in items %}
{{ loop.index }}
/* condition check*/
{% if loop.index == 2 %}
<div class="spectra-promo col-md-6 spectra-offer-info">
<h3>{{ item.content }}</h3>
{% endif %}
/* condition check*/
{% if loop.index == 3 %}
<h5>{{ item.content }}</h5>
<div class="choose-offer">
<div class="left-sec">
{% endif %}
/* condition check*/
{% if loop.index == 4 %}
<p>{{ item.content }}</p>
<div class="right-sec">
<p><i class="fa fa-angle-right" aria- hidden="true"></i></p>
</div>
</div>
</div>
{% endif %}
{% endfor %}
{% endif %}
{% endif %}

twig load data from content into field.html.twig

<div class="quote">
<span{{ attributes }}>
{%- for item in items -%}
{{ item.content }}
{%- endfor -%}
</span>
</div>
I tried..
{{ content.field_content_1| Body }} - this errors out
I'm trying to pull in the:
Quotes (Field) / field_content_1 / Entity reference

Resources