Comma separated list in twig - php

What is the shortest (and clearest) way to add comma after each element of the list except the last one?
{% for role in user.roles %}
{{ role.name }},
{% endfor %}
This example will add comma after all lines, including the last one.

Don't know about shortest but this could be clear. Try the following to add comma after all lines in the loop except the last one:
{% for role in user.roles %}
{{ role.name }}
{% if not loop.last %},{% endif %}
{% endfor %}
Shorter version as suggested in comments:
{% for role in user.roles %}
{{ role.name }}
{{ not loop.last ? ',' }}
{% endfor %}

This works with Symfony 2.3.x but should work with every 2.x version:
{{ user.roles|join(', ') }}

{{- not loop.last ? ',' : '' -}}

{{ user.roles|column('title')|join(', ') }}

Since the OP asked for iterating on name key of a role.
Shortest would be:
{{ user.roles|column('name')|join(', ') }}
where user.roles is a list of user roles.

Here is how I managed to print author names (in authors array) in some scientific publication format using twig's local loop variable in for loop-
{% spaceless %}
{% for author in authors %}
{{- loop.last ? ' and ' : (not loop.first ? ', ') -}}
{{- author -}}
{% endfor %}
{% endspaceless %}
The output is something like
For 1 author
Author1
For 2 authors
Author1 and Author2
For 3 or more authors
Author1, Author2, and Author3

Related

Print Twig variable x times based upon randomized range

I am using Twig and Timber for a WordPress project. I have the following loop in my template that prints my custom post type titles into a HTML structure.
{% for company in companies %}
{% set dot = "<div class='company-dot'></div>" %}
{% set range = range(10, 20) %}
{{dot}}
{{random(range)}}
<div class="company">
<div class="company-dot dot-active"></div>
<p class="dot-caption">{{ company.title }}</p>
</div>
{% endfor %}
I would like to print my {{dot}} variable x amount of times based upon the number that is generated by {{random(range)}}. How can I do this?
The simplest solution would be to iterate random(range) times with a for loop:
{% for i in 0..random(range(10, 20)) %}
{{ dot }}
{% endfor %}
I don't really know Twig but my guess is that you could to the following:
{% for i in random(range) %}
{{dot}}
{% endfor %}
You already know how to use range, just use it again :
{% set dots_count = random(range) %}
{% for dot_index in range(1,dots_count) %}
{{dot}}
{% endfor %}
{{dots_count}}
Here is a fiddle : https://twigfiddle.com/ko595z

Symfony Form Collection Theming but feed some data

Symfony 3.3
I have a form of my Voyage entity
Voyage entity has a Collection in it, named cities, collection of entity City.
And so do the form with the Collection named cities.
The user first use the form and create an instance of Voyage and add some cities to it, I managed to customise the prototype and render it via javascript when the user click "add city" button.
The form is rendered this way for the interesting part (cleaned version without html):
{% extends "#User/layout.html.twig" %}
{% form_theme form.cities '#Prototype/city.html.twig' %}
{% block content %}
{{ form_start(form) }}
{{ form_errors(form) }}
{{ form_row(form.cities) }}
{{ form_rest(form) }}
{{ form_end(form) }}
{% endblock content %}
The theme for the 'form.cities' :
{% block collection_widget %}
{% import '#Prototype/prototype.city.twig' as proto %}
{% spaceless %}
<div class="collection">
{% if prototype is defined %}
{% set attr = attr|merge({'data-prototype': proto.city(prototype)|escape }) %}
{% endif %}
<div {{ block('widget_container_attributes') }}></div>
<div id="container-cities">
{# Here I will add the cities via javascript when user add one #}
</div>
</div>
{% endspaceless %}
{% endblock collection_widget %}
The macro file used in this theme and imported as proto :
{% macro city(widget, id, name, zip) %}
{% spaceless %}
<div
class="added-city border-gray"
data-id="{{id|default('__id__')}}"
id="{{name|default('__name__')}}">
{{name|default('__city_name__')}} ({{zip|default('__zip__')}})
{{ form_errors(widget) }}
{{ form_widget(widget) }}
</div>
{% endspaceless %}
{% endmacro %}
My general problem : When the user wants to edit its instance of Voyage, it already has some cities in it. How can I render them ? How can I access the cities variable from within the theme.
My partial solution : I wanted to extract the 'container-cities' block from the theme file to the rendered html where the form is initialy rendered and where I can access the variables and do this :
{% import '#Prototype/prototype.city.twig' as proto %}
{% for city in form.cities %}
{{ proto.city(city, city.name) }}
{% endfor %}
But it give me this error :
Neither the property "name" nor one of the methods "name()", "getname()"/"isname()"/"hasname()" or "__call()" exist and have public access in class "Symfony\Component\Form\FormView".
(It doesn't fail on city.id probably because of some other field named id)
My question :
How can I access the cities within the theme and render them with my macro ?
Or
How to access to the cities items where I render the form, because the form.cities doesn't seem to be the actual City entity Collection, and get rid of that error ?
Thanks
I finally solved it, it was that simple :
I just used this in the form theme :
{% for city in form %}
{{ proto.city(city, city.vars.value.id, city.vars.value.name, city.vars.value.zip) }}
{% endfor %}

Force number field of symfony2 to use point as decimal separator in any locale

how to force format to number field in Symfony2 ?
My application is translated to different languages. The problem is that in French I have 1234,56 but it's very important to render field with point 1234.56
I tried that config but it didn't worked:
twig:
number_format:
decimals: 2
decimal_point: '.'
thousands_separator: ''
Any help will be appreciated.
I had to override number_widget
{%- block number_widget -%}
{% if value is not empty %}
{% set value = value|replace({',': '.'})|number_format(precision|default(scale|default(2)), '.', '') %}
{% endif %}
{%- set type = type|default('text') -%}
{{ block('form_widget_simple') }}
{%- endblock number_widget -%}

How do I make a simple count loop in Wordpress Timber(Twigg)?

How do I make a simple count loop in Wordpress Timber(Twigg)?
So basically just a loop like this:
($i = 0;0 < 3;i++){
echo $test[i];
}
You could use
{% for value in test %}
{{ value }}
{% endfor %}
that is safer than
{% for i in 0..2 %}
{{ test[i] }}
{% endfor %}
because in second version you have to care about index (is setted? and so on) whereas in the first you don't.
Of course if your final goal is to print only three elements from the array you should consider slice filter
{% for value in test|slice(0, 3) %}
{{ value }}
{% endfor %}

Symfony2 Twig Change / Replace Value

I'm new here. I'm also new in working with Symfony2.5.
I want to replace a value with another, better would be to change it via array.
It's hard to explain - here are some code parts:
Recources/Views/register.html.twig:
{% for user in list_user %}
{{ user.Id }}
{{ user.isAdmin }}
{{ user.isActive }}
{% endfor %}
Here I generate the array to send to register.html.twig which looks like this:
Controller/AccountController.php
$user = $this->getDoctrine()
->getRepository('SeotoolMainBundle:User')
->findAll();
return $this->render(
'SeotoolMainBundle:Account:register.html.twig',
array('form' => $form->createView(), 'list_user' => $user)
);
It correctly outputs for isAdmin and isActive 0 or 1. Now I want to replace this output with for example isActive = 1 should Output "Active", isActive = 0 shut Output "Not active".
I hope you understand what I mean and can help me find the correct way to do this.
Thank you guys,
kind regards,
Marvin
Can't you just use an "if"?
{% for user in list_user %}
{{ user.Id }}
{{ user.isAdmin }}
{% if user.isActive %}
Active
{% else %}
Inactive
{% endif %}
{% endfor %}
You can also use the ternary operator, which is more compact.
{% for user in list_user %}
{{ user.Id }}
{{ user.isAdmin }}
{{ user.isActive ? 'Active' : 'Inactive' }}
{% endfor %}

Categories