How to check if menu item contains a word using twig - drupal

in the menu.html.twig theme template, I want to check if a menu item title contains a specific word.
so I tried this codes, but none of them worked.
{% elseif menu_level == 1 and 'separator' in item.title %}
{% elseif menu_level == 1 and 'separator' in item.title.raw %}
{% elseif menu_level == 1 and 'separator' in item.title|render %}
and I have the items: 'separator 1', ' separator 2', 'separator'
but couldn't solve the problem!

item.title will give raw text, and the code to check is:
{% if 'separator' in item.title %}
You should check:
menu_level is 1 for your case. For my case, its coming zero (0)
check expected spelling/case of string 'separator'
You can print these variables for debugging purpose.
{{ item.title }}
{{ menu_level }}

Related

Set default value if null in twig

I am looping my results in twig view..
{% for item in items %}
<li> {{ item.userId.firstName }} {{ item.userId.lastName }} </li>
{% endfor %}
I want to set default value 'User unknown' if the user id in database is NULL .
Like: {% if item.userId is null %} --> than set default value
Note: I am aware of using if else here but as I have this fistName - lastName in numerous palace, I wanted to avoid using if else in every part. I wanted to set that default value everywhere in case userId is null without repeating the code in every place.
How can I accomplish that?
EDIT
You can set a variable by using:
{% set name = item.userId is null ? 'User unknown' : item.userId.firstName ~ ' ' ~ item.userId.lastName %}
If by setting you mean outputting 'User unknown', a simple if else statement would do the trick
{% for item in items %}
{% if item.userId is null %}
<li>User unknown</li>
{% else %}
<li> {{ item.userId.firstName }} {{ item.userId.lastName }} </li>
{% endif %}
{% endfor %}
It may be easier to set defaults in the code that is rendering the output, where items is being sent to Twig. array_merge is often used for this - $item = array_merge($defaultItem, $item);. Here, $item overrides the value set in defaults.
Within the templates, you can also use the null-coalescing operator ?? on individual fields: {{ item.userId.firstName ?? 'unknown firstName' }}
Maybe a bit late, but Twig seems to have a filter for default values:
https://twig.symfony.com/doc/2.x/filters/default.html

Translate dynamic variable in twig

How do I translate this in twig? I have this variable in twig that is an array:
$array = [
['number' => 7, 'name' => 'foo'],
['number' => 8, 'name' => 'bar'],
['number' => 10, 'name' => 'baz'],
// ... and so on and so forth
]
Would like it to be something like this:
The variables are 7 times for foo, 8 times for bar, and 10 times for baz.
Or
The variables are 7 times for foo and 10 times for baz.
Or
The variable is 7 times for foo.
Tried with something like this:
{% set last = array|last %}
{% set array = array|slice(0, array.length - 1) %}
{% trans %}
<p>The variables are
{% for i in array %}
{{ i.number }} times {{ i.name }},
{% endfor %}
, and {{ last.number }} number of {{ last.name }}
.</p>
{% endtrans %}
Thanks!
Try this
The variables are
{% for item in array %}
{% if array|length > 1 and loop.last %}
and
{% endif %}
{{ item.number }} times for {{ item.name }}{% if loop.last %}.{% elseif array|length > 2 %}, {% endif %}
{% endfor %}

Nested flexcontent using Wordpress ACF fiels

I'm using ACF's flexcontent, however to allow the user to add different types of content in the same row, I've nested more flexcontent elements inside it.
The goal for the end user to be able to add either text or image, and drag them to decide the order.
I have other types of flexcontent for images, video, text etc. These are working fine.
The structure of my ACF fields is
--text
--image etc (all other flexcontent blocks)
--content_mixed = flexcontent
----column = flexcontent
--------text= flexcontent
----------------text (text field)
--------image=flexcontent
----------------imagegroup (group)
--------------------------------image
--------------------------------caption
My code is:
{% set flexcontent == post.get_field('flexcontent')%}
{% if flexcontent %}
{% for item in flexcontent %}
{% if item.acf_fc_layout == 'text' %}
{% elseif item.acf_fc_layout == 'images' %}
//images
{% elseif item.acf_fc_layout == 'content_mixed' %}
// text + image, this shows up
{% for subitem in post.subitem.get_field('column') %}
{% if subsubitem.acf_fc_layout == 'text' %}
//text
{% endif %}
{% if subsubitem.acf_fc_layout == 'imagegroup' %}
// image
//image caption etc
{% endif %}
{% endfor %}
{% endif %}
{% endfor %}
{% endif %}
I think I'm in the wrong iteration but having trouble finding how to get to the right one. I can't see any of the content I've added to the post.
the print_r of {{ item.column }} (inside the first flexcontent field, "content_mixed") is
Array
(
[0] => Array
(
[acf_fc_layout] => text
[text] =>
Lorem Ipsum doret sit amet
)
[1] => Array
(
[acf_fc_layout] => image
[imagegroup] => Array
(
[image] => Array (
//all image info
)
Your print_r is telling you that item is an array of arrays. So you can just loop over that instead:
{% for subitem in item.column %}
{% if subsubitem.acf_fc_layout == 'text' %}
//text
{% endif %}
// etc.
{% endfor %}
As pointed out in the comments, your chained post.subitem.get_field() call will not do what you expect.
BTW, you don't need the if flexcontent check before your loop. Twig is very tolerant of empty values and will just ignore attempts to loop over null, false, etc. Less nesting is much easier to read.

Render choice options separately

I have researched quite a bit and also read the documentation but this thing remains unanswered.
I want to render choice-options separately in twig and a {%for%} loop doesn't seem to work.
Here's the situation:
I have 3 radio buttons which are supplemented with 3 different blocks of html each (therefore I cannot do a loop over the segments as they are different).
Form-Extract (form 'payment'):
array(
'choices' => array(
'paypal' => 'payment.method.paypal',
'bank' => 'payment.method.bank',
'check' => /** #Ignore */
),
'label' => 'payment.method',
'expanded' => 'true',
How could I access the different choice options in twig? I have tried
{{ form_widget(form.payment.method[bank]) }}
and also
{{ form_widget(form.payment.method.bank) }}
Thanks so much for your help.
Stefffen
You might want do it this way:
{% for method in form.payment %}
{% if method.vars.value == "paypal" %}
#Render it in a paypal awesome way
{{ form_widget(method) }}
{{ form_label(method) }}
{% else if method.vars.value == "bank" %}
#Render it in a bank awesome way
{{ form_widget(method) }}
{{ form_label(method) }}
{% endif %}
{% endfor %}
Hope it helps

Directly access a form field's value when overriding widget in a twig template

What I want to do is get variables stored in form view.
{% form_theme edit_form _self %}
{% block field_widget %}
{% spaceless %}
{% set type = type|default('text') %}
<input type="{{ type }}" {{ block('widget_attributes') }} {% if value is not empty %}value="{{ value }}" {% endif %}/>
{# MY CODE #}
{% if type == "file" %}
<a class="BOpreview" href="{# NEED TO REPLACE VAR HERE #}">Aperçu</a>
{% endif %}
{# MY ATTEMPT #}
{{ form.title.get('value') }}
{{ form.vars.value.url }}
{% endspaceless %}
{% endblock field_widget %}
My form has properties like url, title, etc and I am trying to access them here to use it in the field widget block.
I searched for it and came on https://groups.google.com/forum/?fromgroups=#!topic/symfony2/onor9uFte9E that suggested:
{{ form.title.get('value') }}
{{ form.vars.value.url }}
which didn't work for me.
Note: If I do a var_dump on $form->createView() in my controller, I get:
object(Symfony\Component\Form\FormView)[331]
private 'vars' =>
array (size=15)
'value' =>
object(Panasonic\TestEtAvisBundle\Entity\Product)[168]
protected 'reviewArray' =>
object(Doctrine\ORM\PersistentCollection)[234]
...
protected 'testArray' =>
object(Doctrine\ORM\PersistentCollection)[221]
...
protected 'fbshareArray' =>
object(Doctrine\ORM\PersistentCollection)[317]
...
private 'id' => int 2
private 'name' => string 'Nom du produit' (length=14)
private 'title' => string '<span>Titre </span>' (length=19)
private 'image' => string 'bundles/testetavis/uploads/product/0d9d9550.png' (length=47)
private 'fbImage' => string 'bundles/testetavis/uploads/product/facebook//product_e928cd96.jpg' (length=65)
private 'description' => string '<span>Descriptif </span>' (length=24)
private 'url' => string 'http://www.google.com' (length=21)
private 'creationDate' =>
object(DateTime)[210]
...
private 'modificationDate' =>
object(DateTime)[209]
...
private 'isDeleted' => int 0
'attr' =>
array (size=0)
empty
'form' =>
&object(Symfony\Component\Form\FormView)[331]
'id' => string 'panasonic_testetavisbundle_producttype' (length=38)
'name' => string 'panasonic_testetavisbundle_producttype' (length=38)
'full_name' => string 'panasonic_testetavisbundle_producttype' (length=38)
I want to access that url for instance but can't seem to be able to do it after many variations. Including use of {{ value }}, {{ value.url }}
But inspite of vars, I can do {{ full_name }} and get panasonic_testetavisbundle_producttype.
Any ideas?
Edit2: I found out the real problem...
Edit3: Seeing that this question is quite popular I decided to clarify on what I attempted to do in case it helps someone in the same situation. If you rely strictly on what the question asks, as I stated from my research and that Besnik supported are indeed correct.
Now what I wanted to do is for every input type file, get url from object used to render form and append a preview link, using retrieved url, beside the input type file.
If you try to get the form var of an input type "file" like this "{{ form.vars.value.url }}" in my code, this doesn't work since, if I recall correctly, you receive a token instead of the url stored inside the object.
You can access the current data of your form via form.vars.value:
{{ form.vars.value.title }}
See Symfony2 Forms documentation: http://symfony.com/doc/current/book/forms.html#rendering-a-form-in-a-template
Dump vars by using dump function:
{{ dump(form.vars.value) }}
If you are using subforms or want to have a value of a specific field:
{{ form.FIELD.vars.VALUE }}
You can access values of the parent parent from a widget block using form.parent.vars
For example, we want to render the value from a type text field called primerNombre we will need
{{ form.vars.value.primerNombre }}
If we wanted to render the name of one of the children we will need
{% for hijo in form.hijos %}
<td><div align="left">{{ form_widget(hijo.vars.value.primerNombre) }}</div></td>
{% endfor %}
Good luck!
In Symfony > 3 you may use:
form.vars.value.Entity.someValue
Edit2:
Finally, I was indeed getting the value of the current row in {{ value }} here:
{% block field_widget %}
{% spaceless %}
{% set type = type|default('text') %}
<input type="{{ type }}" {{ block('widget_attributes') }} {% if value is not empty %}value="{{ **value** }}" {% endif %}/>
{# MY CODE #}
{% if type == "file" %}
<a class="BOpreview" href="{{ value }}">Aperçu</a>
{% endif %}
{% endspaceless %}
{% endblock field_widget %}
But in my case I get a token instead of the value since I am using input type file. This is due to a security measure in Symfony2.

Resources