How to get value of option from select - twig

I contributed in back-office a select attribute with two options but when I'm doing
{{ ez_field_value(content, 'value') }}
I get 0 or 1 according to I contributed on back-office.
How to get value of this select attribute ?

I don't think there's a readily available way to get the clean value of the option from Twig.
What you can do though is use {{ ez_render_field(content, 'my_field') }} which will render the option name in a div element, but with added ezselection-field CSS class attached to it, like so:
<div class="ezselection-field">My option</div>

Related

How to run an object's method in twig without rendering what it returns [duplicate]

I have seen the twig documentation about do tag, but I don't understand its use/useful.
The docs says the follow:
The do tag works exactly like the regular variable expression ({{ ...
}}) just that it doesn't print anything:
and show an example:
{% do 1 + 2 %}
What to solve exactly this tag ?
Good question! I found a link on GitHub to when this was proposed which might add some further info:
Sometimes you want to do things, or call some stuff, and ignore the output. For example if you use a |shift filter to remove some data from an array, doing {{ arr|shift }} will output the removed item, which is not always desirable.
Of course it's possible to do {% set null = arr|shift %}, which won't
output anything, but it also looks weird.
The example in the docs is poor as it explains nothing at all, as you pointed out.

What is the proper Twig syntax to display a ACF custom field linked to a Taxonomy term

What would be the proper Twig syntax to print display a custom Taxonomy name of (genres) The ACF field name is book_genre and a the custom Taxonomy of "Business" is selected in this WordPress custom-post, The Twig syntax here {{ post.book_genre }} only outputs the ID of the Taxonomy on the page, but I need it to print the Taxonomy name of: "Business" I have also tried {{ post.terms('category') }} to no avail this just prints "Array"
Okay I finally was able to figure it out, it seems like {{ post.meta('book_genre') }} did what I needed it to do and print out the term name of "Business" (example only)
However in the ACF Groups the Return Value of "Term Object" has to be selected.

Drupal 8 Twig User ID?

I'm new to Drupal & Twig and all I need is in my custom theme a twig expression to output the current user's ID. I can't find anything in the template comments, only if a user is logged in true / false.
Is there a simple way to get the ID of the current user? I'm not sure how to implement custom methods in a theme.
thanks!
Hello bobomoreno,
I would suggest you use the module Bamboo Twig.
The Bamboo Twig module provides some Twig extensions with some useful functions and filters aimed to improve the development experience.
You could then enable the sub-module Bamboo Twig - Loaders:
drush en bamboo_twig_loader -y
Finally, you will be able to use the Twig function bamboo_load_currentuser:
<!-- Get Current User -->
{% set user = bamboo_load_currentuser() %}
<div>{{ user.name.value }}</div>
<div>{{ user.uid.value }}</div>
You can find the complete official documentation there.
In your theme find file yourthemename.theme and add following code:
function yourthemename_preprocess(&$vars, $hook)
{
$vars['uid'] = \Drupal::currentUser()->id();
}
now if you edit your twig template for html, page, region, block, field, form element... you can use 'uid' token in your twig. It works for all hooks
If you only need the ID in user.html.twig, it's {{ user.id }}
Here's how D8 now works, in two lines of executable code:
<?php
// This code returns the current user ID.
$account = \Drupal::currentUser();
return $account->id();
The display name is not a field you can configure in {{ content }}. You can get it directly from the user entity:
{{ user.displayname }}
Reference for the php method: AccountInterface::getDisplayName
The Twig Tweak module is very small and yet very powerful. You can get the current user id with drupal_token('current-user:uid') I am using it to pass the current user id to a view like this:
{{ drupal_view('view_name', 'embed_1', drupal_token('current-user:uid')) }}

Accessing individual fields in Drupal 8 views templates

I'm having trouble doing something that I think should be relatively simple drupal 8 views.
I have a content type called Countries. I would like to display the 3 latest country nodes on my homepage in a views block. Each country is displayed with the class "views-row" on the container div. I am using views--view--unformatted--countries--block_1.tpl to template the output.
I would like to output something like the following markup:
<a class="view-row-1" href="/link/to/node">
<img src="source-of-teaser-image.png">
<h3>Title of node</h3>
</a>
<a class="view-row-2" href="/link/to/node">
<img src="source-of-teaser-image.png">
<h3>Title of node</h3>
</a>
<a class="view-row-3" href="/link/to/node">
<img src="source-of-teaser-image.png">
<h3>Title of node</h3>
</a>
The problem I'm having is accessing individual fields in the template. If I use a view mode, I can access individual fields. If I select "show fields" in the view, I can add a field for "view result counter" and "path", which would allow me to add the "view-row-N" class and link the a tag to the node, but I can't get access to the fields individually. I have the {{row.content}} variable, but any attempt to dig further into the variable (eg row.content.field_name) gives me nothing and calling a {{dump(row.content)}} crashes the website.
I can't output this as a view mode for 2 reasons. I don't have access to the "view result counter" or "path" fields in a view mode and, even if I had these variables, some fields would be nested inside others (The image and title are nested inside the )
I feel this should really be as simple as
<a class="view-row-{{ row.content.view_result_counter }}" href="{{ row.content.path }}">
etc but I've tried everything I can think of. Am I completely on the wrong path? Twig and I are not getting along so far...
I have figured a way using kint.
Inside your views-view-unformatted.html.twig use the following code to display your individual fields:
{% for row in rows %}
{{ row.content['#view'].style_plugin.render_tokens[ loop.index0 ]['{{ YOUR_FIELD_NAME }}'] }}
{% endfor %}
Using content/view mode works in your case.
1/ In "views-view-unformatted.html.twig" you can use "loop.index" in the "for" loop to get index of the current row and add it to the "row_classes" variable.
2/In the twig template for the node you can use something like :
<a href="{{ path('entity.node.canonical', {'node': node.id}) }}">
{{ content.field_img }}
{{ node.getTitle()}}
</a>
3/You will probably get extra html but you can get rid of most of it by overriding relevant templates.
I am not sure if it's what you expect, but you can override field template:
Enable Twig debugging: https://www.drupal.org/node/1903374
Inspect your page in browser (if site is in debug mode there are comments in html with paths to templates for each element).
For example this is field template: core/themes/stable/templates/views/views-view-fields.html.twig
Copy required template into your theme folder
Add or modify markup.
You can debug template using {{ dump(variable) }} or {{ kint(variable) }}
In your case you should be using views-view-fields--countries--block_1.html.twig instead of views-view-unformatted--countries--block_1.html. twig file.
Views fields template will iterate on all rows of result. Your views-view-fields--countries--block_1.html.twig should contain below code -
<div>
<a class="view-row" href="{{variable-to-print-path }}">
<img src="{{ image-path }}">
<h3>{{ fields.title.content</h3>
</a>
</div>
You can check the fields array by using kint function like - {{ kint(fields) }}
Check for image path and anchor path variable from output of kint function.
If you want to do this in views-view-unformatted--countries--block_1.html. twig, then you can access the field values like below -
{% for row in rows %}
{% set photo = file_url(row['content']['#row']._entity.field_page_photo.entity.fileuri) %}
<li><img src={{ photo }} class="img-responsive img-circle"></li>
{% endfor %}
The solution is simple use the views fields template.
I created a new template under themes/templates folder:
views-view-fields--VIEW-NAME.html.twig
And now you can access your fields values like this:
{{ fields.field_NAME.content }}
If you want to access Individual fields in Views Twig Template along with Row Information,
Override Views Fields Template in your custom theme :
views-view-fields--VIEW-NAME.html.twig
To get the row index in the same file, Use :
{{ row.index }}

Wrap contextual html around a specific twig variable {{ product.name }}

I want to automatically wrap some html, lets say <span data-id=".."> when I call {{ product.name }} in my twig template.
So when in a twig template, I use {{ product.name }}, I want the output to be: <span data-type="product" data-id="8" data-prop="name">My product name</span>. I cannot use twig filters or macros, since I really need the template syntax to be {{ product.name }}, so the end-user (template designer), does not have to care about it.
The reason I need this is because I am building an on-page editting tool for twig templates, so I need to know the contexts of those variables from within HTML.
I have tried to override the Compiler that the Twig_Environment uses, but I cannot seem to alter the output of the twig variable node.
How can I do this?
EDIT
I wanted to mention that I need this to use the {{ product.name }} syntax, since other designers will work with those templates outside of Symfony 2. I want to make almost all twig variables editable in the front-end, so a solution with filters or macros can indeed work, but it kills the usability and readability of the platform I am writing. There is no public API currently in twig that can achieve what I want, that is why I am fiddling with the twig compiler. I do not have the required knowledge of the Twig internals to achieve this. If someone could point me into a direction that would be great!
UPDATE 2
I have found a place where I can achieve what I want. Every GetAttr node is compiled to $this->getAttribute($someContext, "property"). So if I can change the subclass of compiled twig template, I can achieve what I want. By default all twig templates extend from Twig_Template. I want to extend this method.
How can I change the subclass of all compiled twig templates?
UPDATE 3
I've found a way to use my own base class for all compiled twig templates. I can simply set it as an option on the twig environment, see this link. I hope to get it working tomorrow and I will post a proper answer on how I solved it all together. Not sure how I will handle escaping, since that will happen after the $this->getAttribute() is called.
I think macros are the best candidates for those kind of wrappings.
For example:
main.twig
{% import "macros.twig" as macros %}
{{ macros.display_product(product) }}
macros.twig
{% macro display_product(product) %}
<span data-id="{{ product.id }}" data-prop="name">{{ product.name }}</span>
{% endmacro %}
Context
product:
id: 8
name: My Georgeous Product
Result
<span data-id="8" data-prop="name">My Georgeous Product</span>
See fiddle
I've solved it by wrapping the PrintNode that is created when parsing a VAR_START token (inside the twig parser) with my own EditablePrintNode. In that node I traverse the expression that is compiled by the print node and get the necessary property path and pass that as an argument to a wrapper function around the default twig escape function that is compiled by the PrintNode.
I suggest to write a custom filter. You can find the doc here about how to write and configure in your environment
// an anonymous function
$filter = new Twig_SimpleFilter('my_custom_product_filter', function ($product) {
return '<span data-id="'.$product->getId().'" data-prop="name">'.$product->getName().'</span>';
});
You need to register as described in the doc
then you can use as follow:
{{ myProduct|my_custom_product_filter}}
Hope this help

Resources