Problem/Motivation
Using simple twig filters with a pipe dont work, but wrapping with a {% filter foo %}
"kinda" does
examplate in themes/classy/templates/field/field--node--title.html.twig
{{ item.content|upper }}
throws an error:
Warning: mb_strtoupper() expects parameter 1 to be string, array given in twig_upper_filter() (line 1276 of vendor/twig/twig/lib/Twig/Extension/Core.php).
but using
{% filter upper %}
{{ item.content }}
{% endfilter %}
everything (almost) works as expected when the filter block is used as a function
If theres html inside of it using {% filter upper %}
will result in outputting markup as escaped tags
<P>LOUD & NOISE </P>
even more interesting is if i want to remove markup that a wysiwyg editor have edited and use
{% filter striptags %}
{{ item.content }}
{% endfilter %}
special characters like &
is converted.
taking it one step further and go raw on the item.content
{% filter upper %}
{{ item.content|raw }}
{% endfilter %}
Do we really want ppl to do |raw on the strings, but yeah that will happen if thats the only way.
Proposed resolution
Make string manipulation possible using drupal OR update the docs https://www.drupal.org/node/2357633 and tell and make it clear that themers cant be trusted to do string manipulation that everybody else that uses twig can http://twig.sensiolabs.org/doc/templates.html#filters
Remaining tasks
User interface changes
API changes
Data model changes
Comment | File | Size | Author |
---|---|---|---|
#12 | kint-dump.png | 47.83 KB | mortendk |
Comments
Comment #2
mortendk CreditAttribution: mortendk commentedComment #3
mortendk CreditAttribution: mortendk commentedComment #4
mortendk CreditAttribution: mortendk as a volunteer commentedComment #5
msankhala CreditAttribution: msankhala commentedComment #6
mortendk CreditAttribution: mortendk as a volunteer commentedComment #7
mortendk CreditAttribution: mortendk as a volunteer commentedComment #8
star-szrThis is because you are trying to run a string filter on a render array which is not possible. Agreed docs could be better but you need to |render the array first before you run other filters :)
Comment #9
mortendk CreditAttribution: mortendk as a volunteer commented{{ item.content|render|upper }}
still gives me escaped formatted html<P>LOUD & NOISE </P>
so its kinda back to the same issue of "not really working" ;)Even more interesting if i wanna strip out tags from a string (lets say i wanna use it for some data-attribute something and i do a
{{ item.content|render|striptags }}
then an & gets printed out as & - which isnt really whats expected.So even with |render|filter im still not getting what is expected, and that will force me onto a quest of "getting my data the way i want" -> lets see where i can poke (finding the frontend stick of epic-poke-making-security-issues-nobody-thought-about *evil laughter*
Comment #10
mortendk CreditAttribution: mortendk as a volunteer commentedi have added to the documentation to use
{{ item|render|filter }}
to avoid the confusion.We might gonna make it very explicit to people that everything is autoescaped, so if you want to manipulate a string you cant really do it if an enduser have added the data in as html in anyway.
Comment #11
star-szrIt sounds then like item.content is not marked as safe, not sure what type of value it is.
kint(item.content)
ordump(item.content)
might be worth a peek.Comment #12
mortendk CreditAttribution: mortendk as a volunteer commentedin this case its a text field with potential html text inside of it (why i in the first place wanted to remove that before i added it into the link so i could use it for a tool til and an data attribute
ala :
kint dump
Comment #13
star-szrOkay I see what you mean now. We may have to consider whether some filters can create a new Markup object but there would have to be limits there I think.
To get what you want in your case I think you could do
{{ item.content['#text']|striptags }}
Edit: To give more background I forgot this morning when replying that rendering returns a Markup object. Once you print and manipulate that string it's no longer safe, that's why it's getting escaped.
Comment #14
joelpittetIt would be nice to preserve safeness on some filters, but the manipulation *could* open a security hole. I tested with striptags and it was hard to crack, but maybe that's just time and patience. A bit hesitant to recommend
|raw
, but if I knew where the source was coming from, I'd be likely using that, but like the Issue summary says,Comment #18
Pranali.addweb CreditAttribution: Pranali.addweb at AddWeb Solution Pvt. Ltd. commentedIn my case filters are working very well without using filter block. For example, if we use capitalize filter it will return first value with an uppercase. Let me explain it as an example. My problem gets resolved with this, as we can try it for a better approach.
Apart from upper there are few other filters are also available to modify the capitalization, We should try them for a better approach and modify capitalization style of our strings.
Hope this helps you.
Comment #19
joelpittetI'm going to close this, but thanks for the extra help showing @dharmdeep.addweb.
Comment #20
Stephen OllmanNot sure if this will help anyone, but the following fixed my issue.
Changed in the theme page.html.twig
{% if page.sidebar_first|trim %}
to
{% if page.sidebar_first|render|trim %}
Comment #21
snable CreditAttribution: snable as a volunteer and commentedTHX, made my day!
However, i cannot figure out why e.g. the piped trim filter does not work without the additional piped render filter.
Comment #22
TunprogThis worked for me thanks:
<h2 id="{{ item.content|render|replace({' ': '-'}) }}">Hello</h2>