Twig - Trim exact string only - twig

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

Related

Twig equivalent of lcfirst

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

Trim whitespace (trailing newline) at the end of included Twig template

I’m trying to include a Twig template inside another, but there is undesirable whitespace which is caused by the trailing newline in the included template.
My use case is that the include takes place mid-sentence, just before a comma, and I don’t want any whitespace before the comma.
Base template:
Né le {{ include("date.html.twig", {date: date}) }}, décédé le…
Included template:
<time datetime="...">
{{- date.format() -}}
</time>
Desired result :
Né le 6 mai 1977, décédé le…
Actual result :
Né le 6 mai 1977 , décédé le…
I can confirm the trailing newline is the cause of the issue, but removing it is not a viable solution to me since most tools are configured to add it if it’s missing.
Is there any way to trim this trailing newline?
I found the solution while writing the question:
Ending the included template with a Twig tag seems to be enough. So I ended up wrapping the content in a spaceless filter:
{% apply spaceless %}
<time datetime="...">
{{- date.format() -}}
</time>
{% endapply %}
Technically using {% if true %} … {%- endif %} also works, but is much less understandable.
- modifiers are still needed inside <time> because spaceless only removes whitespace between HTML tags, not inside.

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

Array to string conversion, with split

I have a text like: 000325175
and I want to format it as: 000 325 175.
Nothing's easier (in theory) with the split filter, as:
{{ mynumber|split('', 3) }}
But I get a
An exception has been thrown during the rendering of a template ("Notice: Array to string conversion")
However I can apply a slice filter without any problem.
{{ mynumber|slice(9, 14) }}
So I don't understand. Thanks for help
The split filter return an array (with the spitted values), you should only iterate over the result to display it as follow:
{% for partial in mynumber|split('', 3) %}
{{ partial}}
{% endfor %}
Here a working solutions
EDIT:
You can also use the join filter and concatenate the results as example:
{{ mynumber|split('', 3)|join(' ') }}

How to write that path in string to be parsed - Twig

I set links in this way in twig:
{% set link = '('~product.price~)'~product.name~'' %}
The problem is how to fill the link
{% set link = '('~product.price~)'~product.name~'' %}
This gives me the error: A hash key must be a quoted string, a number, a name, or an expression enclosed in parentheses (unexpected token "punctuation" of value "{"
{% set link = '('~product.price~)'~product.name~'' %}
Unexpected token "name" of value "restaurant" ("end of statement block" expected)
can you please help me :(
The link will also have an id argument.
The only thing I can think of is writing a filter which takes te id as argument and replaces the empty link, but I'm not quite sure it will work, and it doesn't seem like a good solution.
You should not use parentheses within {% %} blocks.
Furthermore, unless you have a specific reason for putting the whole markup for the link in a variable, you might want to consider creating links like this:
{{ product.name }}

Resources