Set html id attribute dynamically in Twig - symfony

I'm trying to set the id of an element using a variable in a Twig template (not a form) without using JavaScript.
The template code looks like this:
{% set show_id = 'show' ~ entity.id %}
{{ dump(show_id) }}
<div class="event_option" id="show_id">
show
</div>
The show_id variable is dump'ed correctly, but when I try to use it as the html id in id="show_id", the id that gets assigned to the div is the string "show_id", and not the actual value of show_id. I get the same result when no parenthesis are used when assigning the html id, as in id=show_id. How can I access the Twig variable when assigning the html id attribute?

You should enclose with double bracket to tell Twig to print the value of variable
<div class="event_option" id="{{show_id}}">
show
</div>

Related

Dynamically generate / omit HTML attribute in Twig

I want to generate a div with a specific HTML attribute present or absent in it, in function of if a variable my_var has been defined or not. If it has been defined, its value should be used as the according attribute.
my_var is either not defined or equal to a value consisting of several words separated by a space (software needs these, I know it's not usual...).
I've tried the following:
<div class="container" {{ my_var ? "data-my-var='" ~ {{ my_var }} ~ "'" : ""}}>
</div>
But this escapes the quotes I use and yields sth like this in my output, with my_var = hello there how are you:
<div class="container" data-my-var="hello there how are you">
</div>
This does not change when I escape the quotes using
"data-my-var=\"" ~ {{ my_var }} ~ "\""
instead of what's written above.
I've also tried to simply omit the quotes, so do sth like:
"data-my-var=" ~ {{ my_var }}
which resulted in the attribute data-my-var being output with no quotes whatsoever; hence only recognizing the first word of the value of my_var.
So how can I reach what I want?
Variables and concatenations with variables are not marked as safe by default. You will need to apply the filter raw to mark the output as safe. Also you can omit the second part if you just return an empty string
<div class="container"{{ my_var ? (' data-my-var="' ~my_var ~ '"')|raw }}>
</div>
demo
Another method, as commented by #Bossman is to use an {% if ... %}{% endif %}

Adding a parameter to a partial breaks all my expressions in that partial

I'm iterating over an array and generating a partial for every item, which returns a name. I added a parameter called text and set it to "hello!".
{{#each array}}
{{> partial text="hello!" }}
{{/each}}
Adding the parameter to the partial causes the other 'name 'expression to not display. Instead, only "hello!" is shown. Here is the code for my partial:
{{ text }}
{{ name }}
I think your issue is, that you're losing your scope inside that partial, which is the normal behaviour handlebars has.
When you call a partial all parameters that are available within your template won't be there anymore, if you dont pass them to that partial.
So if you want to access {{ name }} inside your partial. you have to call your partial like so :
{{> partial text="hello!" name=name }}
Partials are similar to calling a function in other programming languages, except for that you name your parameters in the call.
Take a look at this pseudo code:
foo = "Hello world!"
myPartial(bar=foo);
function myPartial(bar) {
echo bar; // bar will be "Hello world!"
}
Maybe it helps.
Also feel free to check the handlebars partial documentation to guide you further

Django_table2 TemplateColumn usage

I just read the folowing article and i would like more information about the first method using TemplateColumn. I would like to produce two pseudo columns for edit and delete methods of each record.
edit.html
> <a href="{% url some_url_edit record.pk %}" class="tbl_icon
> edit">Edit</a>
delete.html
> <a href="{% url some_url_del record.pk %}" class="tbl_icon
> delete">Delete</a>
2 pseudo columns that does not exist in DB
class MyTable(tables.Table):
column_edit = tables.TemplateColumn(edit.html)
column_delete=tables.TemplateColumn(delete.html)
If that is correct according to the article how record.pk is passed on every template to get the required information about its key?
If you want to edit or delete an object then you'd need to use a model table:
class MyModelTable(tables.Table):
name = tables.columns.Column()
edit = tables.TemplateColumn('<a href='{% url "edit_my_model_instance" record.id %}'>Edit</a>', verbose_name=u'Edit', )
delete = tables.TemplateColumn('<a href='{% url "del_my_model_instance" record.id %}'>Delete</a>', verbose_name=u'Delete', )
class Meta:
model = models.MyModel
Notice how we use record.id to pass it the id of each row to the url template tag in order to output the correct edit/delete url.
i am afraid that your code is a bit faulty as someone must use the following commands to get properly displayed the images inside the columns:
edit = tables.TemplateColumn('<img src=\'{% load staticfiles %} {% static "images/edit.jpg" %}\' / width="25">',verbose_name=u'Edit',)
delete = tables.TemplateColumn('<img src=\'{% load staticfiles %} {% static "images/delete.jpg" %}\' / width="25">',verbose_name=u'Delete',)
I would like to ask if i could use inside tables.py bootstrap css for better rendering of columns and data tables?

Translate the value of twig variable

Is it possible to translate the value of twig variables in a template with the 'trans' tag?
Say for instance I am passing a product to my template. This product has a definition with a trans tag e.g {{ product.definition|trans }}. This definition could either be in EN or DE or some other language. How could I translate the definition.
What are you trying to do is not a good way, It would look like this:
messages.en.yml
product:
definition:
some_value1: Some value 1
some_value2: Some value 2
and in template, you would do something like this:
{% set definition_value = product.definition %}
{% set trans_definition = 'product.definition.' ~ definition_value %}
{{ trans_definition|trans }}
it'll work, if it finds the key. What if it cant find it?
That's why you should use DoctrineBehaviors from KnpLabs, which handles all the dynamic translations for you..
If {{ product.definition }} equals 'cellphone' the following should work.
message.language.yml:
'cellphone': This will work!
However if you want to map it with the 'product' key in your message file like this:
product:
'cellphone': This also works
add the key to the twig template like so:
{{('product.'~product.definition)|trans }}

How to pass an Twig expression as a parameter to a template, and then execute it with template's context?

I define a template which built select dropdown inputs for my forms:
<p id="{{key | ucfirst}}">
<span>{{label}} : </span>
<select required disabled>
{% for d in data %}
<option value="{{attribute(d, optionValue)}}" {{(attribute(d, optionValue) == selectedValue)?'selected'}}>{{attribute(d, optionIntitule)}}</option>
{% endfor %}
</select>
<span><em>{{initialValue | default("")}}</em></span>
</p>
Then I just need to include it, and passing it some data:
{% include 'selectForm.twig' with {'label': 'Manager'
, 'key': context.manager.id
, 'initialValue': projet.manager.username
, 'data': users
, 'keyValue': 'id'
, 'keyIntitule': 'username'
, 'selectedValue': projet.manager.id) }
%}
It works fine, but I want to do more. For instance I would like to show a value more usefull for end user into option's label: <option>Username (email)</option> instead of <option>Username</option>
So I think I can't use anymore the attribute function.
I thought I could pass an expression to my template like following:
{% include 'selectForm.twig' with {..., 'keyIntitule': "#{d.username (d.email)}"} %}
But the expression is evaluated with immediate context, not template's one. So it doesn't work.
I also tried with template_from_string but I don't suceed in (I never used this function before...)
Is there a way to pass an expression to another template, and make it evaluate the expression with it's own context?
If you want to block the immediate context you can use include function instead of include tag. Then you can disable context this way (example taken from the documentation) :
{# only the foo variable will be accessible #}
{{ include('template.html', {foo: 'bar'}, with_context = false) }}
I found the solution with Twig's template_from_string function:
{% include 'selectForm.twig' with {..., 'keyIntitule': template_from_string("{{d.username}} ({{d.email}})")} %}
And then I use keyIntitule variable as a template:
<option value="{{attribute(d, optionValue)}}">{% include(keyIntitule) %}</option>
Works also with:
<option value="{{attribute(d, optionValue)}}">{{ include(keyIntitule) }}</option>
If you working with objects you could set keyIntitule to uniqueName and in the user entity define new method:
public function getUniqueName()
{
return sprintf('%s (%s)', $this->getUsername(), $this->getEmail());
}
Twig will call corresponding getter method. In this case uniqueName transforms to getUniqueName()

Resources