Conditionnal display with twig - twig

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.

Related

How to reduce duplication in Twig template

I have an if/else condition in a twig template which switches the out tag of a block of code, however the inner block is the same. Is there a way to reduce the duplication without creating a separate file?
This is what I have at the moment:
{% if condition %}
<a href="">
{{ content }}
</a>
{% else %}
<span>
{{ content }}
</span>
{% endif %}
I was hoping to do something such as:
{% if condition %}
<a href="">
{% include mycontent %}
</a>
{% else %}
<span>
{% include mycontent %}
</span>
{% endif %}
{% mycontent %}
{{ content }}
{% endmycontent %}
Is such a thing possible?
If you don't want to use extra files you could use macro's :
{% import _self as macro %}
{% macro foo(content) %}
{{ content }}
{% endmacro %}
{% for condition in [0, 1, 0, 1, ] %}
{% if condition %}
{{ macro.foo('Bar') }}
{% else %}
<span>{{ macro.foo('Bar') }}</span>
{% endif %}
{% endfor %}
fiddle
What you want to do has to be done using the normal syntax. an extra file. and include this file.
But if u want to do this without extra file. use the {% set variablecontent = "put content here" %} and then in your "{% mycontent %}" part u put {{ variablecontent }}
hope this helps

Wrap content by an element that satisfies a condition in Twig

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 }}

Navigation link works on mobile but not on desktop

i have this website http://sds-test.nowcommu.myhostpoint.ch/de (please use the "de" at the end) and the last link of the navigation "RECHENZENTRUM" does not works on desktop but works on mobile. How can i solve it? This is the twig code:
{% extends 'partials/base.html.twig' %}
{% set show_onpage_menu = header.onpage_menu == true or header.onpage_menu is null %}
{% macro pageLinkName(text) %}{{ text|lower|replace({' ':'_'}) }}{% endmacro %}
{% block javascripts %}
{% if show_onpage_menu %}
{% do assets.add('theme://js/singlePageNav.min.js') %}
{% endif %}
{{ parent() }}
{% endblock %}
{% block bottom %}
{{ parent() }}
{% if show_onpage_menu %}
<script>
// singlePageNav initialization & configuration
$('#navbar').singlePageNav({
offset: $('#header').outerHeight(),
filter: ':not(.external)',
updateHash: true,
currentClass: 'active'
});
</script>
{% endif %}
{% endblock %}
{% block header_navigation %}
{% if show_onpage_menu %}
<ul class="navigation">
{% for module in page.collection() %}
{% set current_module = (module.active or module.activeChild) ? 'active' : '' %}
<li class="{{ current_module }}">{{ module.menu }}</li>
{% endfor %}
{% set datacenter_page = page.find('/services/datacenter') %}
<li>{{ datacenter_page.menu() }}</li>
</ul>
{% else %}
{{ parent() }}
{% endif %}
{% endblock %}
{% block content %}
{{ page.content }}
{% for module in page.collection() %}
<div id="{{ _self.pageLinkName(module.menu) }}"></div>
{{ module.content }}
{% endfor %}
{% endblock %}
The 'rechenzentrum' link is rendered correctly, and copying the link location via right click gives a correct URL that opens a seemingly correct page. So the template rendering is fine.
The link has two onclick handlers attached to it, though. Probably one of them fails and thus prevents navigation. (The JS is minified so I did not try to debug it.)

Is it possible to turn on spaceless mode only in certain situations in twig?

I want to do something like this:
{% if compress %}{% spaceless %}{% endif %}
...
{% if compress %}{% endspaceless %}{% endif %}
I'm trying to pass ['compress' => true] to the template from PHP to turn on spaceless mode. But it causes an error; template tags need to be nested properly.
Is there any technique that would let me turn spaceless on/off from PHP?
You would have to restructure your template to do something like this instead.
{% import _self as example %}
{% macro stuff(obj) %}
output stuff with {{ obj.name }}, etc...
{% endmacro %}
{% if compress %}
{% spaceless %}
{{ example.stuff(bla) }}
{% endspaceless %}
{% else %}
{{ example.stuff(bla) }}
{% endif %}
Using macros avoids you have to duplicate the content. The import statement at the top is important, so don't forget it.
page.twig:
{% block page %}
page content
{% endblock %}
index.twig:
{% extends 'page.twig' %}
{% block page %}
{% if compress %}
{% spaceless %}
{{ parent() }}
{% endspaceless %}
{% else %}
{{ parent() }}
{% endif %}
{% endblock %}

Dynamic block name in TWIG

I need to add multiple blocks in my template, every with different name.
{% for item from items %}
{% block item.name %}sometext{% endblock %}
{% endfor %}
But I get error. How can I do this ?
In
Dynamic block names are not possible with Twig. There has been a discussion about it over at GitHub.
You can load blocks dynamically using the block function.
{% for item in items %}
{{ block( item.name )|raw }}
{% endfor %}
Twig documentation for the block function
If I understood the question correctly, you can do this (use parent context):
parent.html.twig
{% for item from items %}
{% set currentLoopItemName = item.name %}
{% block item_loop %}sometext{% endblock %}
{% endfor %}
override.html.twig
{% extends "base.html" %}
{% block item_loop %}
{% if item.name == 'custom' %}
// do something
{% else %}
{{ parent() }}
{% endif %}
{% endblock %}
I was attempting to do the same thing and found a solution using the template_from_string function.
_items.html.twig
{% for item in items %}
{{ '{% block ' ~ item.name ~ ' %}'}}
sometext
{{ '{% endblock %}' }}
{% endfor %}
enter code here
page.html.twig
{% embed template_from_string(include('_items.html.twig')) %}
{% block someItemName %} someDifferentText {% endblock %}
{% endembed %}
What's happening is the block tags are initially being created as text. Then we use the include function to get the rendered content of _items, as a string. Finally, we convert that string to a working template (which we can embed or extend).
This works because the template_from_string function will create and compile a template at runtime, where as normally twig is compiled before hand and unchanged at runtime.

Resources