Can I modify a global Liquid variable from inside a Jekyll include? - global-variables

I would like to create to separate Jekyll includes that can both reference the same common variable. Here is a simplified scenario.
I create _include/setter.html with the following Liquid code:
{% globalString | append: include.add | append: "," %}
Then I create _include/getter.html with the following Liquid code:
we have {{ globalString }}
Then in my page I put:
{% include setter.html add = "one" %}
{% include setter.html add = "two" %}
{% include getter.html %}
I'd like to see a result something like we have one,two, as a result.
But of course globalString does not exist, so this cannot work. I can't seem to create new variables in site or page that can be seen from includes. For now I am awkwardly working around this with capture. Is there a better way to pass data out of an include in Jekyll?

This can be done setting the global variable before calling the includes and passing it as a parameter:
_includes/setter.html:
before: {{include.globalString}}<br>
{% assign globalString = include.globalString | append: include.add | append: "," %}
after: {{globalString}}<br>
_includes/getter.html: we have {{ include.globalString }}
Then:
{% assign globalString = "" %}
{% include setter.html add = "one" globalString=globalString%}
{% include setter.html add = "two" globalString=globalString%}
{% include getter.html globalString=globalString%}
Would output:
before:
after: one,
before: one,
after: one,two,
we have one,two,
Update
It also works without passing the "global" variable as a parameter, the only requirement is to define it before calling the includes:
_includes/setter.html:
before: {{globalString}}<br>
{% assign globalString = globalString | append: include.add | append: "," %}
after: {{globalString}}<br>
_includes/getter.html: we have {{ globalString }}
{% assign globalString = "" %}
{% include setter.html add = "one" %}
{% include setter.html add = "two" %}
{% include getter.html %}

Related

adding the default filter apparently "disables" the filter raw

I'd like to display the raw value of a variable, if this one is empty, the default value N/A should be shown instead.
The code below doesn't work, but it shows even the html tags
{% set my_var = '<b>hello world!!</b>' %}
{{ my_var | default('N/A') | nl2br | raw }}
As strange as this may seem, the following code works, knowing that I just removed the default filter
{% set my_var = '<b>hello world!!</b>' %}
{{ my_var | nl2br | raw }}
What's going on?
Try this :
{% set my_var = '<b>hello world!!</b>' %}
{{ my_var|default('N/A')|raw|nl2br }}

Symfony2 Twig Conditional Template Name

I'm looking for a way to check in my twig template if the name of the template contains a special word. If that is the case I want to proceed with assigning some stuff. Here is a general idea I have in mind.
{% if [sth like app.request.template_name or sth like that] in `product` %}
// Do some stuff
{% endif % }
Can you guys help me with this?
If you're creating separate template files then you'll know the names and can hardcode the values:
template_1.html.twig:
{% set some_var = 1 %}
{% set another_var = 2 %}
template_2.html.twig:
{% set custom_var = 5 %}
Update:
If you want the template name, you can use:
{% if 'product' in _self.getTemplateName() %}
{# Do stuff #}
{% endif %}

Set a Variable with a Twig Macro

I have to set a variable with a macro, that returns a number, so I have this macro:
{% import _self as self %}
{% macro function_size(field) %}
{% import _self as self %}
{# initial Setup #}
{% set field_length = 0 %}
{# Field #}
{% for key, value in field %}
{% if not (key starts with "#") %}
{% set field_length = field_length + 1 %}
{% endif %}
{% endfor %}
{{ field_length }}
{% endmacro %}
The Macro loops through the entries of a field and returns the count of values, that don't start with "#".
So I set a variable with that value:
{% set image_size = self.function_size(content.field_teaser_image) %}
ATTENTION: With this you will set the Variable with Twig Markup. (You can see that when you debug the variable afterwards.)
To get a number/integer as value you have to convert it to a String (that will be interpreted as a number if you calculate with it)
{% set image_size = image_size.__toString %}
With this I set the Variable successfully with a macro.
My Question: Is this a bad practice, are there better ways how to set an Variable?
Thank you!
Two ways to set variables for twig are fine in my opinion.
1. Use theme and other hooks (inside theme or any module) and pass variable from php,
2. create twig extension/filter
Examples:
Filter:
http://leopathu.com/content/create-custom-twig-filter-drupal-8
Extension:
http://symfony.com/doc/current/templating/twig_extension.html

Difference between {% include '' %} and {{ include('') }} in Twig

It's possible to include a file in two different ways:
{% include 'fic.html.twig' %}
{{ include('fic.html.twig') }}
What is the difference between the two methods?
Source:
http://twig.sensiolabs.org/doc/tags/include.html
http://twig.sensiolabs.org/doc/functions/include.html
Tags are less flexible than functions, for example:
If you want to store contents of a file in a variable if you want to repeat it twice:
{% set content = include('test.twig') %}
Instead of:
{% set content %}
{% include 'test.twig' %}
{% endset %}
If you want to add filters:
{{ include('alert.twig') | upper }}
Its tag equivalent:
{% set temp %}
{% include 'alert.twig' %}
{% endset %}
{{ temp | upper }}
You see, {{ include }} instead of {% include %} will not change the world, but remove some complexity when you need to do tricky stuffs using Twig.
Also, according to the documentation, it is recommended to use {{ include() }} to fit with best practices:
{{ }} is used to print the result of an expression evaluation;
{% %} is used to execute statements.
From Twig's changelog:
* 1.12.0-RC1 (2012-12-29)
* added an include function (does the same as the include tag but in a more flexible way)
I think it's the same functionality, but while {% include '' %} is a tag, the {{ include('') }} is a function. Maybe if you want to overwrite the function it can be easier than a tag.
From Symfony 2.8 (LTS) documentation
2.3 The include() function is available since Symfony 2.3. Prior, the {% include %} tag was used.

Twig / Symfony2 - using a variable inside array merge

{% set var_name1 = "hello" %}
{% set var_name2 = "there" %}
{% array1|merge({var_name1: var_name2}) %}
I was hoping the code above would add this to array1:
hello:there
...but it adds:
var_name1:there
I've tried wrapping {{ }} around var_name1. Is it possible to add a record to an array and use a variable for the key?
Enclose the key name in brackets:
{% array1|merge({(var_name1): var_name2}) %}
Note that if var_name1 is a numeric value, it won't work.
You'll have to concat it with a string value :
{% set array1 = array1|merge({(var_name1~'_'): var_name2}) %}

Resources