I have a question, I have this code :
{% set texte_article = 'Simple text' %}
{% set url_article = 'simple/url' %}
What is the idea of text_article|twitter_share..., I don't understand what do |. Can you help me please ? Thx in advance
And what is the difference between : {{ 40|lipsum }} and {{ lipsum(40) }} ?
the filter method is :
public static function getShareLink($s_url)
{
$a_params = array(
'url' => 'url',
'hl' => 'share'
);
return self::URL . http_build_query($a_params, '', '&');
}
| is to apply a Twig fliter.
I guess you have a twitter_share_link function in your project which need url_article as parameter
Related
I have the following variables in twig:( I can see them with kint)
data.po_user_setting.us_highlight_color1 = '#008080'
data.po_user_setting.us_highlight_color2 = '#00FFFF'
data.po_user_setting.us_highlight_color3 = '#FFFF00'
data.po_user_setting.us_highlight_color4 = '#FF0000'
data.po_user_setting.us_highlight_color5 = '#FF00FF'
and
verse.po_verse_highlight.hl_rating = Returns [1-5]
How can I show the dynamic variable like this? Neither of these lines work:
{{_context['data.po_user_setting.us_highlight_color' ~ verse.po_verse_highlight.hl_rating]}}
{{attribute(_context, 'data.po_user_setting.us_highlight_color' ~ verse.po_verse_highlight.hl_rating)}}
The problem you are facing is the variable you want to access is actually an array.
With your current code, twig is looking for a variable called e.g., data.po_user_setting.us_highlight_color.foo, translated to $_context['data.po_user_setting.us_highlight_color.foo']
To actually access the variable you want, you would need to treat the variable like an array:
{{ {{ _context['data']['po_user_setting']['us_highlight_color'~ verse.po_verse_highlight.hl_rating] }} }}
This is quite long to type every time, so to reduce the typing you could use a macro or extend twig
macro
{% macro get_array_value(context, key) %}
{% set value = null %}
{% for key in key|split('.') %}
{% set value = loop.first ? context[key]|default : value[key]|default %}
{% endfor %}
{{ value }}
{% endmacro %}
As macro's don't have access to the special variable _context you would to pass this every time when you want to call the macro, e.g.
{% import _self as macros %}
{{ macros.get_array_value(_context, 'data.po_user_setting.us_highlight_color' ~ verse.po_verse_highlight.hl_rating) }}
extending twig
<?php
$twig->addFunction(new \Twig\TwigFunction('get_array_value', function ($context, $variable) {
$keys = explode('.', $variable);
if (empty($keys)) return;
$value = $context[array_shift($keys)] ?? [];
foreach($keys as $key) {
$value = $value[$key] ?? [];
}
return !empty($value) ? $value : null;
}, ['needs_context' => true,]));
Then you can call this function like the following in twig
{{ get_array_value('data.po_user_setting.us_highlight_color' ~ verse.po_verse_highlight.hl_rating) }}
I'm trying to make a twig template to get a variable from a custom block, when I do a {{ dumb() }} it shows me the variables and their values but when I call for the variable it won't show it, even when i call the variable with dumb {{ dumb(title) }} it tells me is NULL. Could anyone help me understand what is the mistake?
Block: onyx_experiencia.php
/**
* Provides a 'Test' Block.
*
* #Block(
* id = "onyx_experiencia",
* admin_label = #Translation("Servicios OnyxGroup"),
* category = #Translation("Servicios OnyxGroup"),
* )
*/
class onyx_experiencia extends BlockBase implements BlockPluginInterface {
/**
* {#inheritdoc}
*/
public function build() {
$title = 'TestTitle34';
$desc = 'Test text 24';
$test_array = array(
'#title' => $title,
'#description' => $desc
);
return $test_array;
}
block.module: onyx_experiencia.module
<?php
/**
* Implements hook_theme().
*/
function onyx_experiencia_theme($existing, $type, $theme, $path) {
return array(
'block__serviciosonyxgroup' => array(
'template' => 'block--serviciosonyxgroup',
'render element' => 'elements',
'variables' => array(
'title' => 'TitleTest',
'description' => 'DescriptionTest'
),
),
);
}
Twig File: block--serviciosonyxgroup.html.twig
{#
/**
* #file
* Profile for onyx_experiencia block.
*/
#}
<h3>Featured Events</h3>
<p>Test: {{ title }} </p>
<p>Test: {{ description }} </p>
<ol>
{% for key, value in _context %}
<li>{{ key }}</li>
{% endfor %}
</ol>
{{ dump(content) }}
Result: This is the result i get
UPDATE Different way still not working
As seen on your screenshot:
The variables live in the variable content, not in _context
Your current template code assumes they in live _context though as they aren't prefixed with anything.
{{ title }} equals <?= isset($_context['title']) ? $_context['title'] : null; ?>
So u'd need to change the template to something like
<h3>Featured Events</h3>
<p>Test: {{ content['#title'] }} </p>
<p>Test: {{ content['#description'] }} </p>
In my symfony3 project, I have a form field with label "I accept the cgu" with a link on the 'cgu'.
How can I translate the label containing the link, as I must generate the link with {{path('')}} in twig ?
I tried something like that :
{{ form_row(form.valid, {'label' : 'annonces.form.valide_cgu_cgv' | trans ({'cgu_link' : {{ path('page_statique', {'page' : 'cgu'})}}, 'cgv_link' : {{ path('page_statique', {'page' : 'cgv'})}} }) |raw }) }}
but it does not work...
Any idea ?
Thanks all !
When you are under {{ }}, you're writting an expression, so you can't put nested {{ }}.
You can try with:
{{
form_row(form.valid, {
'label' : 'annonces.form.valide_cgu_cgv' | trans({
'cgu_link' : path('page_statique', {'page' : 'cgu'})
'cgv_link': path('page_statique', {'page' : 'cgv'})
})
})
}}
Lets say I have an associative array like so:
{% set settings = { 'foo':'bar', 'cat':'mouse', 'apple':'banana' } %}
To use this data I would do the following:
{{ settings.foo }}
{{ settings.cat }}
{{ settings.apple }}
However, I wondered if there is a way to extract the keys to variables, and the values to values? Essentially the same as the PHP Extract function. So I can just do this instead:
{{ foo }}
{{ cat }}
{{ apple }}
My very amateurish attempt to do this started out like this:
{% for key,val in settings %}
{% set key = val %}
{% endfor %}
But obviously that doesn't work (or I wouldn't be here). Is there another approach I could take?
Thanks,
Mark
As most things in Twig this can be done by extending Twig
ProjectTwigExtension.php
class ProjectTwigExtension extends Twig_Extension {
public function getFunctions() {
return array(
new Twig_SimpleFunction('extract', array($this, 'extract'), ['needs_context' => true, ]),
);
}
public function extract(&$context, $value) {
foreach($value as $k => $v) $context[$k] = $v;
}
public function getName() {
return 'ProjectTwigExtension';
}
}
Register class in Twig
$twig = new Twig_Environment($loader);
$twig->addExtension(new ProjectTwigExtension());
template.twig
{{ extract({'foo': 'bar', }) }}
{{ foo }} {# output : bar #}
(sidenote) Seems you can't do this by using a closure (see example below) because the compiler of Twig passes the variables in an array, thus creating a copy
With closure
$twig->addFunction(new Twig_SimpleFunction('extract', function (&$context, $value) {
foreach($value as $k => $v) $context[$k] = $v;
}, ['needs_context' => true, ]));
Compiled result
echo twig_escape_filter($this->env, call_user_func_array($this->env->getFunction('extract')->getCallable(), array($context, array("foo" => "bar", "foobar" => "foo"))), "html", null, true);
Is it possible to check if given variable is string in Twig ?
Expected solution:
messages.en.yml:
hello:
stranger: Hello stranger !
known: Hello %name% !
Twig template:
{% set title='hello.stranger' %}
{% set title=['hello.known',{'%name%' : 'hsz'}] %}
{% if title is string %}
{{ title|trans }}
{% else %}
{{ title[0]|trans(title[1]) }}
{% endif %}
Is it possible to do it this way ? Or maybe you have better solution ?
Can be done with the test iterable, added in twig1.7, as Wouter J stated in the comment :
{# evaluates to true if the users variable is iterable #}
{% if users is iterable %}
{% for user in users %}
Hello {{ user }}!
{% endfor %}
{% else %}
{# users is probably a string #}
Hello {{ users }}!
{% endif %}
Reference : iterable
Ok, I did it with:
{% if title[0] is not defined %}
{{ title|trans }}
{% else %}
{{ title[0]|trans(title[1]) }}
{% endif %}
Ugly, but works.
I found iterable to not be good enough since other objects can also be iterable, and are clearly different than an array.
Therefore adding a new Twig_SimpleTest to check if an item is_array is much more explicit. You can add this to your app configuration / after twig is bootstrapped.
$isArray= new Twig_SimpleTest('array', function ($value) {
return is_array($value);
});
$twig->addTest($isArray);
Usage becomes very clean:
{% if value is array %}
<!-- handle array -->
{% else %}
<!-- handle non-array -->
{% endif % }
There is no way to check it correctly using code from the box.
It's better to create custom TwigExtension and add custom check (or use code from OptionResolver).
So, as the result, for Twig 3, it will be smth like this
class CoreExtension extends AbstractExtension
{
public function getTests(): array
{
return [
new TwigTest('instanceof', [$this, 'instanceof']),
];
}
public function instanceof($value, string $type): bool
{
return ('null' === $type && null === $value)
|| (\function_exists($func = 'is_'.$type) && $func($value))
|| $value instanceof $type;
}
}
Assuming you know for a fact that a value is always either a string or an array:
{% if value is iterable and value is not string %}
...
{% else %}
...
{% endif %}
This worked good enough for me in a project I was working on. I realize you may need another solution.