Striptag only partial stripping - twig

Got a particular case of striptags not stripping all tags.
{% if field_video|render|striptags %}
<li class="nav-item"><a data-toggle="tab" href="#product-vid">{{ field_video['#title'] }}</a></li>
{% endif %}
The above works in removing the "title" according to field value, but leaves the margins and background color. If I use |trim it removes everything, however if a field has "title" value it also strips it.
Additional things I have tried:
|trim is not empty
What else should I look at?

Related

If statement with string length check

I'm trying to check if a string is empty in a twig template but I don't understand this behaviour. I want to show a textarea element when the condition is met. Here's the code:
{% if item.payload.customizationText|length == 0 %}
<textarea class="customization-text">{{ item.payload.customizationText|trim }}</textarea>
{% endif %}
It always shows the textarea, whether the string has something in it or not. Am I missing something?
It's in shopware 6 by the way and the dump() fuction throws an error because it's undefined.
Also, this expression just outputs the string. Is the length expression not available?
{{ item.payload.customizationText|length }}
I believe there is a mistake in the question. It does not make sense to print the variable, only if it is empty.
If you want to show the text area in case the customizationText has some contents, you should use this:
{% if item.payload.customizationText|trim|length %}
<textarea class="customization-text">{{ item.payload.customizationText|trim }}</textarea>
{% endif %}
https://twigfiddle.com/nmk2kq/4
You can try it.
{% if item.payload.customizationText is defined and item.payload.customizationText is empty %}
<textarea class="customization-text">{{ item.payload.customizationText|trim }}</textarea>
{% endif %}

(Twig) How to check if value taken from translation key (as string or array?) exists within product variant title

(Twig) How can I check to see if a product variant title (which is used multi-lingual) in Twig exists within a translation key (which is a string, but I could change this to an array)?
For a webshop theme, I want to replace the "product.variant" variable (which is a platform variable and contains a variant title) with a CSS color swatch. The ecommerce platform doesnt provide a default way to do this, so I have to build a workaround which should work multi-lingual. Webshop-owners can enter their own label (name) for the color variant, so if webshop-owners use the string "Color", or "color", or "Farbe" (german) or whatever label name in whatever language, my workaround should be able to detect that "color label name" and replace this label value with a color swatch (via CSS, for this I need to know the label value, which is a color name like "blue", and in my CSS I guess I'll have to sum up all color names in as many languages as possible to make it work, I'm afraid, but this is ok). In my thinking I need to use a custom translation key so webshop-owners can enter the color name labels they want to work with, and compare these values with the "product variant" variables which are derived from the ecommerce platform. Can't figure out the right way to do so, anybody who can help me out? Much obliged!
This I tried:
{% for variant in product.variants %}
{% if theme.cstm_translkey_colorswatch_labelname | split(';') in variant.title %}
<p style="background-color: green;color: yellow">Hi, show me a color swatch please!</p>
{% endif %}
{% endfor %}
This code below works, but it uses just 1 variant label name ('Color:'), and I need it multi-lingual):
{% for variant in product.variants %}
{% if 'Color:' in variant.title or 'color:' in variant.title %}
{% set colorSwatches = true %}
{% set colorName = variant.title | trim('"Color: ') %}
{% if colorName not in colorNamesArray %}
{% set colorNamesArray = colorNamesArray | merge([colorName]) %}
{% endif %}
{% endif %}
{% endfor %}
My goal is to have an array of color names that works in all languages that the webshop runs (and where each color name exists just once) that I can replace with a CSS color swatch (this last part is not so much the problem).
(added:)
Variant.title is the system variable for product variants to work with, it's a string that can look like a simple "Size: L", but can also consist of 2 or more attributes, like "Size: L, Color: Blue, Occasion: Casual" (like a matrix of variants). From this value I need to derive whether there's a "color" attribute (but: in all languages the shop offers), and if so, replace this color attribute with a CSS color swatch in the color of the color attribute value (the part after "Color: "), while the order for the attributes can differ (first "Color", or maybe last or in the middle?). That is because web merchants can enter their own variant names/labels, in any order they want, that's what makes it complicated (for me ;).
The other variable "theme.cstm_translkey_colorswatch_labelname" is my own effort to try to work with a custom translation key for webmerchants to define which keys they want to use (and also in what languages) to use as label name for the color variants, so I can use this to compare that to the product "variant.title". They can enter the value (string) for this translation key in the backoffice. But not sure if this is the way to go...
The split will transform the string into an array. This means you can't use instraight away. You would need to loop all "languages":
{% for color in label|split(';') %}
{% for title in titles %}
{% if color|lower in title|lower %}
{{ title }}
{% endif %}
{% endfor %}
{% endfor %}
demo
Do note this would be easier if you would split up the attributes in title in seperate fields or use somthing like trans to translate color on the fly.

Set a property value in an existing twig object

I would like to define a twig object that contains two properties :
The first one is a short text
The second one is a large text (so, i need to use {% set %}{% endset %} to keep readability of the template)
I first tried like this :
{% block principal %}
{% set a_form_help = {'help_toggle_label': 'See the big form field tip', 'help_content': ''} %}
{% set a_form_help.help_content %}>
<h1>This is rules for the field</h1>
<p>A looonng text that will be contained in a collapsed block</p>
<p>And several lines of tips for this field</p>
{% endset %}
{% endblock %}
But Twig complains about the use of the dot in the second {% set %} tag (for setting the large text content in the help_content property).
I've found this message (Twig - Why does it not allow us to set object / array values?) and then done this workaround by using a temporary variable:
{% block principal %}
{% set tmp_help_content %}>
<h1>This is rules for the field</h1>
<p>A looonng text that will be contained in a collapsed block</p>
{% endset %}
{% set a_form_help = {'help_toggle_label': 'See the big form field tip', 'help_content': tmp_help_content} %}
{{ dump(a_form_help) }}
{% endblock %}
I've used a a temporary variable since using the merge() filter would give the same result.
Is this workaroud a good practice or is there a better/cleaner way ?
Thanks in advance for any tip|advice ! :-)
There is no clean way to do it in twig.
Is this workaroud a good practice or is there a better/cleaner way ?
It is not a good practice. As twig is a templating language its responsability is only to display data, not to structure it. Your View Object should have been created elsewhere

Symfony, Twig, if conditions for tab highlights according to current route

I am trying to get a list to highlight if it is at its current page (route). However, I also have subpages within the pages of which I also want the list to be highlighted.
I have my menu if statements:
<ul class="menu">
{% if app.request.get('_route') == 'home' %}
<li class="current">Home</li>
{% else %}
<li>Home</li>
{% endif %}
{% if app.request.get('_route') == 'reports' %}
<li class="current">Reports</li>
{% else %}
<li>Reports</li>
{% endif %}
// etc etc
Now in my reports page, the route is /reports/ I have a menu that clicks to "Detail", "Summary", etc it will go to /reports/detail and /reports/summary... I want it so that when users click on those links, the main navigation is still highlighted.
I was wondering if there is an if statement condition something like this:
{% if app.request.get('_route') starts with(?) 'reports' %}
So whenever anyone goes to a route that's a sub page of /reports/, the "Reports" li in the menu will still be highlighted?
I'm not sure if twig has a function for "starts with" but you can check for containment using in
{% if 'reports' in app.request.get('_route') %}
Just to update this question with current information.
As per current (2.x) Twig documentation this is possible the way it is asked for.
To be more specific, the documentation states:
You can also check if a string starts with or ends with another string:
{% if 'Fabien' starts with 'F' %}
{% endif %}
{% if 'Fabien' ends with 'n' %}
{% endif %}
As such, the desired expression is perfectly possible:
{% if app.request.get('_route') starts with 'reports' %}
And works as expected.
There are some good choices on this thread but another option is to pass the route into an array. This is useful if you have dropdown menu items.
The items in the array would be your defined routes.
{% set routes = {
'activities':
[
'walking',
'swimming',
'running'
]
} %}
Then in your menu bar add this to your menu label class.
{% if app.request.attributes.get('_route') in routes.activities %} Do Something {% endif %}

Minus In twig block definition

What's the difference between this:
{%block body %}
and that
{%block body -%}
Just read something about it in the documentation, not sure if this will also apply on {% block ... %} tags.
Twig whitespace control
{% set value = 'no spaces' %}
{#- No leading/trailing whitespace -#}
{%- if true -%}
{{- value -}}
{%- endif -%}
{# output 'no spaces' #}
There's also another example given which trims the whitespace in front of the variable but doesnt't do it at the end - so the effect is only on one side.
{% set value = 'no spaces' %}
<li> {{- value }} </li>
{# outputs '<li>no spaces </li>' #}
The above sample shows the default whitespace control modifier, and how you can use it to remove whitespace around tags. Trimming space will consume all whitespace for that side of the tag. It is possible to use whitespace trimming on one side of a tag
So I think the difference in your given exmaples is that in the first block body there will be a whitespace after the block started. In your second example body - there's none after the block started.
Just read the documentation entry to see how it works.
EDIT
A simple example to demonstrate the example in the docu:
{% set value = 'NO space in source code after/before "value"' %}
<li> {{- value -}} </li>
...
outputs in Firebug in the HTML markup:
Whereas this
{% set value = 'space in source code after "value"' %}
<li> {{- value }} </li>
...
ouputs:
Notice the space between "value" and the closing </li> in the second example. So the minus - erases/trims a whitespace either before, after or on both sides of e.g. a variable.

Resources