Twig equivalent of lcfirst - twig

I'm not able to find a equivalent of lcfirst php function in Twig, my need is to lower only the first letter of a word ?
If such function doesn't exist, what is the best way to do it ?

As discussed in this issue on Github, you could use:
{{ foo[:1]|lower ~ foo[1:] }}
See this working example.

Just add the function into twig by chaining it with a filter, e.g.
$twig->addFilter(new \Twig\TwigFilter('lcfirst', 'lcfirst'));
Then use it inside any twig template like
{{ string | lcfirst }}

You can use a capitalize filter:
{{ 'my first car'|capitalize }}
{# outputs 'My first car' #}
https://twig.symfony.com/doc/1.x/filters/capitalize.html

Related

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>

Drupal8 Twig - convert string to integer

I just started using twig in drupal8. I'm trying to calculate the difference between two numerical drupal8 variables using views.
field_goals_for: 24
field_goals_against: 3
field_goals_difference: should return 21 but returns 1
I tried already something like this (with and without number_formats):
{% set diff = field_goals_for|number_format - field_goals_against|number_format %}
{{ diff }}
I assume the problem is that the two variables are strings instead of int.
There is a way to convert them to int and return the correct result using twig? If not do you have any alternative solution to suggest?
EDIT:
I tried to SUM and also MULTIPLE the two values:
{{ field_goals_for }} = 24
{{ field_goals_against }} = 3
{{ field_goals_for - field_goals_against }} = 0
{{ field_goals_for + field_goals_against }} = 2
{{ field_goals_for * field_goals_against }} = 1
Why are they considered equal to 1 instead of their real value?
EDIT 2: I found the problem. The value that has been to used is field_goals_for__value instead of field_goals_for. Unfortunately I can't find a way to used both of them in the same text field.
stripping off tags was what did the trick for me!
{% set diff = field_goals_for|striptags - field_goals_against|striptags %}
{{ diff }}
try that
{{ diff["#markup"]|number_format(2,',') }}
It works for me.
I had a similar issue - I had to add '#markup' to get it to work.
{{items[0].content['#markup']|number_format/5*100}}
The number_format filter formats numbers. You can control the number of decimal places, decimal point, and thousands separator using the additional arguments.
As example:
{% set diff = field_goals_for - field_goals_against %}
{{ diff|number_format(2,',') }}
Will print:
21,00
Check here a working example.
Hope this help
The number_format filter was added in Twig 1.5
please check your twig version
(sorry this was initially a comment but since I can't comment yet, I wrote an answer)
Try
{{ diff.__toString|number_format(2,',') }}

concat string and variable in twig

I have this in my template
{{ ad.title_de }}
Now I'm incorporating multiple languages, so 'title_de' has to change
I also have a variable 'tld' which is one of de, en , fr
So I'd like to have something like
{% if tld == 'fr' %}
{{ ad.title_fr }}
etc
Any ideas?
Try using the attribute function.
http://twig.sensiolabs.org/doc/functions/attribute.html
attribute(ad, 'content_'~tld) should work.
Try with this:
{{ ad["title_" ~ tld] }}

Twig - using variable

I want to achive this is twig:
{{ form_widget(form.orderItems.0.enabled) }}
{{ form_widget(form.orderItems.1.enabled) }}
{{ form_widget(form.orderItems.2.enabled) }}
....
but the number to be a variable.
I tried this:
{% set index = 0 %}
{{ form_widget(form.orderItems.index.enabled) }}
Error: Method "index" for object "Symfony\Component\Form\FormView" does not exist
and this:
{{ form_widget(form.orderItems.{{index}}.enabled) }}
Error: Expected name or number
and this:
{{ form_widget(form.orderItems.~index~.enabled) }}
Error: Expected name or number
It is possible to achieve this :(
Some digging suggests you use the 'attribute' function - see Accessing array values using array key from Twig.
I suppose that would be something like
form_widget(attribute(form.orderItems, index).enabled)
Unfortunately I can't easily test that at the moment, but it should get you on the right track.
I am solving the same problem now and getting "expected name or number error" when I want to access variable dynamically.
I can not find simple answer, how to dynamically replace some part of variable in twig.
But It works without first dot as was first comment here.
{{ form[othervariable value].vars.label }}
and NOT
{{ form.[value].name }}

Twig - Trim exact string only

I want to trim a string using twig. The documentation for trim is located here.
{{ 'I like Twig!'|trim('!') }}
{# outputs 'I like Twig' #}
The above example trims exclamation marks from the string.
Consider the following:
{{ 'ROLE_USER'|trim('ROLE_') }}
One would think this would trim ROLE_ and return USER. That's not how it works:
{# outputs 'US' #}
This is because the letters E and R are also in ROLE_, hence they are also removed.
How can I circumvent this, perhaps with a regular expression, or replacing only exactly the string I want?
What about the replace filter?
{{ 'ROLE_USER'|replace({'ROLE_': ''}) }}
//outputs
USER

Resources