I am struggling with creating a macro to automatically generate section number and subsection numbers. I had thought the snippet below would work but it is failing to assign the value if not already set. I am sure this is obvious but my lack of jinja experience is showing... or perhaps lack of Python experience... or both!
I get this error.
{% set sectionnumber.value = sectionnumber.value + 1 %}
jinja2.exceptions.TemplateRuntimeError: cannot assign attribute on non-namespace object
{% macro getsectionnumber(type) -%}
{% if subsectionnumber is none %}
{% if sectionnumber is none %}
{% set sectionnumber = namespace(value=0) %}
{% endif %}
{% set subsectionnumber = namespace(value=0) %}
{% endif %}
{% if type == 'section' %}
{% if sectionnumber is none %}
{% set sectionnumber = namespace(value=0) %}
{% endif %}
{% set sectionnumber.value = sectionnumber.value + 1 %}
{{ sectionnumber.value }}
{% endif %}
{% if type == 'subsection' %}
{% set subsectionnumber.value = subsectionnumber.value + 1 %}
{{ sectionnumber.value }}.{{ subsectionnumber.value }}
{% endif %}
my template:
template = """
{% set sectionnumber = namespace(value=0) %}
{% set subsectionnumber = namespace(value=0) %}
{% macro getsectionnumber(type) -%}
{% if type == 'section' %}
{% set sectionnumber.value = sectionnumber.value + 1 %}
{{ sectionnumber.value }}
{% endif %}
{% if type == 'subsection' %}
{% set subsectionnumber.value = subsectionnumber.value + 1 %}
{{ sectionnumber.value }}.{{ subsectionnumber.value }}
{% endif %}
{% endmacro %}
{{ getsectionnumber('section') }}
{{ getsectionnumber('subsection') }}
{{ getsectionnumber('subsection') }}
{{ getsectionnumber('section') }}
{{ getsectionnumber('subsection') }}
{{ getsectionnumber('subsection') }}
"""
print the template:
print(Template(template).render())
result:
1
1.1
1.2
2
2.3
2.4
My code is:
{% for key, value in section.items %}
{% for key_t, value_t in title.items %}
{% if value_t.section_id == key|add:"0" %}
<li class="nav-item-header"><div class="text-uppercase font-size-xs line-height-xs">
{{value.title}}</div> <i class="icon-menu" title="Tables"></i></li>
{% endif %}
{% endfor %}
{% endfor %}
I want to break the for loop when if the condition is true. like as
{% for key, value in section.items %}
{% for key_t, value_t in title.items %}
{% if value_t.section_id == key|add:"0" %}
<li class="nav-item-header"><div class="text-uppercase font-size-xs line-height-xs">
{{value.title}}</div> <i class="icon-menu" title="Tables"></i></li>
{{break}}
{% endif %}
{% endfor %}
{% endfor %}
How is it possible? please help me...
There is no way to break out of a for loop in Django Template. However, you can achieve this by setting a variable and adding an if statement on the top like this.
{% set isBreak = False %}
{% for number in numbers %}
{% if 99 == number %}
{% set isBreak = true %}
{% endif %}
{% if isBreak %}
{# this is a comment. Do nothing. #}
{% else %}
<div>{{number}}</div>
{% endif %}
{% endfor %}
for some additional help check out this link
https://dev.to/anuragrana/for-loops-in-django-2jdi
or check this answer on stack overflow
How to break "for loop" in Django template
I'm using Twig in Views to rewrite output with condition.
{{ field_illus_lycee }}
{% if field_titre_pour_views is defined %}
{% if field_titre_pour_views is not empty %}
{{ field_titre_pour_views }}
{% endif %}
{% else %}
{{ title }}
{% endif %}
<span class="accroche-admin">{{ body }}</span>
I want to display field_titre_pour_views only if it exists and isn't empty, otherwise the regular title should be displayed. But at this point the regular title isn't displayed.Inspired by this
I don't understand which mistake I've made.
EDIT: correct code
{{ field_illus_lycee }}
{% if field_titre_pour_views is defined %}
{% if field_titre_pour_views is not empty %}
{{ field_titre_pour_views }}
{% else %}
{{ title }}
{% endif %}
{% else %}
{{ title }}
{% endif %}
<span class="accroche-admin">{{ body }}</span>
Sometimes, to ask is to find...this code do the trick:
{% if field_titre_pour_views |default %}
{{ field_titre_pour_views }}
{% else %}
{{ title }}
{% endif %}
Auto fixed :)
Hope it would help someone else.
I'm trying to build a simple dropdown menu on drupal 8 by using twig templates. My problem is that I can't find a way to give the dropdown links a class. Here's my code
{#
/**
* #file
* Theme override to display a menu.
*/
#}
{% import _self as menus %}
{{ menus.menu_links(items, attributes, 0, menu_name) }} {# 1. #}
{% macro menu_links(items, attributes, menu_level, menu_name) %} {# 1. #}
{% import _self as menus %}
{# 1. #}
{%
set menu_classes = [
'c-menu-' ~ menu_name|clean_class,
]
%}
{% if items %}
{% if menu_level == 0 %}
<ul{{ attributes.addClass('navbar-nav u-header__navbar-nav') }}>
{% else %}
<ul class="hs-sub-menu list-unstyled u-header__sub-menu u-header__sub-menu-offset animated">
{% endif %}
{% for item in items %}
{%
set classes = [
menu_level ? 'dropdown-item u-header__sub-menu-list-item' : 'nav-item u-header__nav-item',
item.is_expanded ? 'menu-item',
item.is_collapsed ? 'menu-item',
item.in_active_trail ? 'active',
item.below ? 'nav-item hs-has-sub-menu u-header__nav-item hs-sub-menu-opened',
]
%}
<li{{ item.attributes.addClass(classes) }} data-event="hover" data-animation-in="fadeInUp" data-animation-out="fadeOut">
{%
set link_classes = [
not menu_level ? 'nav-link u-header__nav-link',
item.in_active_trail ? 'active',
item.below ? 'nav-link u-header__nav-link',
item.url.getOption('attributes').class ? item.url.getOption('attributes').class | join(' '),
]
%}
{% if item.below %}
{{ link(item.title, item.url, {'class': link_classes, 'data-toggle': 'dropdown', 'aria-expanded': 'false', 'aria-haspopup': 'true' }) }}
{{ menus.menu_links(item.below, attributes, menu_level + 1) }}
{% else %}
{{ link(item.title, item.url, {'class': link_classes}) }}
{% endif %}
</li>
{% endfor %}
</ul>
{% endif %}
{% endmacro %}
I just need to give a class to {{ menus.menu_links(item.below, attributes, menu_level + 1) }} completely independent from its parents.
Is there a way to achieve it? My output is like this
Sublink
I need to change it like this
Sublink
If there's any other way to do so like with custom module or with hooks, please let me know
Achieved the result with following code
{#
/**
* #file
* Theme override to display a menu.
*/
#}
{% import _self as menus %}
{{ menus.menu_links(items, attributes, 0, menu_name) }} {# 1. #}
{% macro menu_links(items, attributes, menu_level, menu_name) %} {# 1. #}
{% import _self as menus %}
{# 1. #}
{%
set menu_classes = [
'c-menu-' ~ menu_name|clean_class,
]
%}
{% if items %}
{% if menu_level == 0 %}
<ul{{ attributes.addClass('navbar-nav u-header__navbar-nav') }}>
{% else %}
<ul class="hs-sub-menu list-unstyled u-header__sub-menu u-header__sub-menu-offset animated">
{% endif %}
{% for item in items %}
{%
set classes = [
menu_level ? 'dropdown-item u-header__sub-menu-list-item' : 'nav-item u-header__nav-item',
item.is_expanded ? 'expanded',
item.is_collapsed ? 'collapsed',
item.in_active_trail ? 'active',
item.below ? 'nav-item u-header__nav-item expanded nav-item hs-has-sub-menu u-header__nav-item',
]
%}
<li{{ item.attributes.addClass(classes) }} data-event="hover" data-animation-in="fadeInUp" data-animation-out="fadeOut">
{%
set link_classes = [
'nav-link',
not menu_level ? 'u-header__nav-link' : 'u-header__sub-menu-nav-link',
item.in_active_trail ? 'active',
item.url.getOption('attributes').class ? item.url.getOption('attributes').class | join(' '),
]
%}
{% if item.below %}
{% set title %}
{{ item.title }}<span class="fa fa-angle-down u-header__nav-link-icon"></span>
{% endset %}
{{ link(title, item.url, {'class': link_classes, 'data-toggle': 'dropdown', 'aria-expanded': 'false', 'aria-haspopup': 'true' })}}
{{ menus.menu_links(item.below, attributes, menu_level + 1) }}
{% else %}
{{ link(item.title, item.url, {'class': link_classes}) }}
{% endif %}
</li>
{% endfor %}
</ul>
{% endif %}
{% endmacro %}
I often have similar boilerplate code in Twig:
{% if (somelongcond) %}
<div>
{% endif %}
<p>Some long content</p>
{% if (somelongcond) %}
</div>
{% endif %}
The problem with the above is if the condition is changed, it can be a maintenance nightmare, I also have to go look all the way down to find the matching if statement and see if the condition is the same.
An alternative is something like this:
{% if (somelongcond) %}
<div>
{% include 'content' %}
</div>
{% endif %}
{% include 'content' %}
But that requires creating a new file, which can become a mess if I need to do this many times.
Is there a better way to do the above.
There is a good example here: https://gist.github.com/jakedohm/39190ec533e69e83b9cee4bdf3898a60
Result:
{% set content %}
<p>Some long content</p>
{% endset %}
{% if somelongcond %}
<div>
{{ content }}
</div>
{% else %}
{{ content }}
{% endif %}
This is a bit shorter
{{ if somelongcond ? '<div>'|raw }}
<p>Some long content</p>
{{ if somelongcond ? '</div>'|raw }}
Then, if the same condition is repeated, you can maybe set it at the top of your file, then if you need to change it you only have to do it once.
{% if somelongcond %}
{% set cond = true %}
{% else %}
{% set cond = false %}
{% endif %}
{{ if cond ? '<div>'|raw }}
<p>Some long content</p>
{{ if cond ? '</div>'|raw }}