How to use ez_image_alias using twig - twig

I wanna use ez_image_alias() function but I dunno what values I have to put in.
Do you have some examples of how to use this function using Twig ?

ez_image_alias Twig function accepts three parameters:
field you wish to render
version info of the content where the field is located
variant name
Starting from your content which is available in a content variable in your template, you would use ez_image_alias function like this:
{% set variation = ez_image_alias(
ez_field(content, 'image'),
content.versionInfo,
'large')
%}
variation variable will now hold an instance of eZ\Publish\SPI\Variation\Values\ImageVariation object which you can use to render the image:
<img src="{{ asset(variation.uri) }}" />

Related

How to show/print same content twice or more using drupal_view in a template?

I have a page where I need to show/print the same content twice. For this, I am using drupal_view.
{{ drupal_view('product_content', 'page_1', node.id) }}
This code works only for the first position and for the second position it doesn't work. What can be done so that the content shows up in both places?
Got the solution from the Drupal community:
When something is rendered, the render system remembers what has been
rendered and won't re-render that. Assign the render output to a twig
variable and print the variable twice:
> {% set product_content = drupal_view( ... )|render %}
> {{ product_content }}
> {{ product_content }}

Convert string into node path

So i am working on a Shopware shop, and i want to read a MediaEntity in Twig. To do so, i am creating a string with the node path (adding the product ID as a variable), which just works fine.
To actually access the MediaEntity, i need to convert this string into a real node path. How do i do that? Or is there maybe another way to create this path?
Here's my code:
{% block component_product_box %}
{{ parent() }}
{% set coverIds = "context.extensions.#{product.coverId}.elements" %}
{{ dump() }}
{% endblock %}
I tried it roughly and something like this should work:
{% set coverIds = _context['extensions'][product.coverId]['elements'] %}
This should solve your problem, I hope.
If you really need to work with a string and "dots" notation, this could be of help:
How to use Twig's attributed function to access nested object properties

Can I mark a Twig variable equally as safe as a captured chunk of text?

Here's a Twig Fiddle. There you will notice this include file:
{# include.twig #}
{{ text }}
And this main file, with several attempts to mark a text variable as safe before passing it to the include file:
{# main.twig #}
1. Pass string with HTML
{{ include('include.twig', { text: '<p>Text</p>' }) }}
2. Pass string with HTML marked safe with raw filter
{{ include('include.twig', { text: '<p>Text</p>'|raw }) }}
3. Pass variable set with string literal marked safe with raw filter
{% set text = '<p>Text</p>'|raw %}
{{ include('include.twig', { text: text }) }}
4. Pass variable set with captured chunk of text
{% set text %}<p>Text</p>{% endset %}
{{ include('include.twig', { text: text }) }}
And here are the results of rendering this template:
1. Pass string with HTML
<p>Text</p>
2. Pass string with HTML marked safe with raw filter
<p>Text</p>
3. Pass variable set with string literal marked safe with raw filter
<p>Text</p>
4. Pass variable set with captured chunk of text
<p>Text</p>
The first attempt establishes the unwanted behavior of HTML escaping. Strategies 2 and 3 attempt to use the |raw filter to avoid the escaping, but both fail. Strategy 4, using the set tag to capture a chunk of text, works perfectly.
The documentation for the |raw filter says:
The raw filter marks the value as being "safe", which means that in an environment with automatic escaping enabled this variable will not be escaped if raw is the last filter applied to it:
The documentation for the set tag says:
If you enable automatic output escaping, Twig will only consider the content to be safe when capturing chunks of text.
Unless I'm missing something, these appear to be two different definitions of "safe", with the one mentioned under the set tag meaning super-extra-safe.
Is there any way to pass super-extra-safe HTML-containing string literals into a template, without polluting my file with ugly chunk-capturing set blocks?
The answer is no, you cannot because twig does not escape static expression. The raw filter is even ignored when compiling the template.
{% set hello = "<strong>Hello</strong>" %}
{% set hello = "<strong>Hello</strong>"|raw %}
The two lines above will compile in the same sourcecode
// line 1
$context["hello"] = "<strong>Hello</strong>";
// line 2
$context["hello"] = "<strong>Hello</strong>";
source
edit:
If you really want to do this, you could either write your own include/set node or add a filter which returns a Twig\Markup
<?php
$twig->addFilter(new \Twig\TwigFilter('safe', function($v) {
return new \Twig\Markup($v);
});
{% include 'text.html' with { 'text': 'Hello <strong>World</strong>'|safe, } %}
Hello World

Execute statement inside conditional

Is it possible to call an executable function inside a Twig conditional statement?
I have a path function and want to output the path if the name variable is empty. Right now I have these two options:
{% path file, 'reference' %} // calling path function
{{ file.name ?: file.path }} // Conditional
But I would like something like:
{% file.name ?: path file, 'reference' %}
Looks like path is a tag instead of a function. If it was a function, you'd use it like this:
{% path(file, 'reference') %}
In comparison, Twig has a function dump, and in Symfony you can use a tag with the same name. Here's how you'd use them:
{{ dump(foo) }} {# function #}
{% dump foo %} {# tag #}
You see the difference?
If path was a function, both of these would probably be possible:
{{ file.name ?: path(file, 'reference') }}
{% do file.name ?: path(file, 'reference') %}
Both are the same, except the second one doesn't print anything.
Because path seems to be a tag, I don't think it's possible to do what you asked. (It's also possible that it's both a tag and a function. If that's the case, use the function instead of the tag.)
Edit: Are you using Symfony? There's a Twig function path in Symfony, but I don't think there's a Twig tag path. Are you sure your code ({% path file, 'reference' %}) is correct?

Variables concatenation

After about an year of using Smarty i wanted to try Twig.
I am facing a problem concatenating a string and a variable to build dynamically the titles of the page when i switch the language.
In Smarty, the controller passes to the template the variables:
$title_it and $title_en
For the title of the page i do <title>{$title_{$lang}}</title> (where $lang is a global variable) and i can switch the values of the variables when i change the language.
I am not able to replicate this behaviour in Twig.
I tried the following methods without having success:
{{ title_ ~ {{ lang }} }} (I think Twig sees the variable "title_" doesn't exists.
'title_'~{{ lang }} (This prints 'title_it' and not it's content)
Is there a way to keep this logic and continuing to use this approach or do i have to handle the titles of the pages differenly?
Thanks a lot,
Manuel
The _context variable holds all variables in the current context, so you can do:
{{ _context['title_' ~ lang]|default }}
This is basically the same as using the attribute function:
{{ attribute(_context, 'title_' ~ lang)|default }}
I would personally use the former as it's more concise and in my opinion clearer.
The default filter is needed when the environment option strict_variables is set to true (the default value is false, but I prefer to set it to true to avoid accidental problems caused by e.g. typos), otherwise you'll get a Twig_Error_Runtime exception if the variable doesn't exist. For example, if you have variables title_en and title_it but try to output the variable title_de (which doesn't exist), you get that exception with the message Key "title_de" for array with keys "title_en, title_it, lang" does not exist.
A more verbose way to check the existence of a variable is to use the defined test:
{% if _context['title_' ~ lang] is defined %} ... {% endif %}
With the default filter you can also provide a default value:
{{ _context['title_' ~ lang]|default('Default title') }}
If you omit the default value (i.e. you do |default instead of |default('some value')), the default value will be an empty string.
See TwigFiddle
I think here the solutions which can fix your problems.
Controller code:
return $this->render('myTwig.html.twig', array(
'lang'=>'en',
'title_en'=>'English Title',
'title_it'=>'Italian Title'
));
Twig Code:
{% set myVar='title_'~lang %}
{{ attribute(_context, myVar) }}
This will display "English Title" on your page.
Here _context variable is a magic variable in twig where you can find all parameters which you passed from your controller to this twig.
attribute(_context,myVar)
it displays the value from passed parameters key to value.
Hope this will solve your problems.
Thanks
I would change the controller to pre-calculate the language dependent value for title before passing it to the twig template. If you are unable (unwilling) to do that, then ...
<title>{% if lang == 'it' %}{{ title_it }}{% else %}{{ title_en }}{% endif %}</title>

Resources