how do I get the raw field values in a twig? - drupal

In Drupal 9, I have created a field[description] which is a List in a content type[country]. In the description list, I added two values like name, capital as dropdown. Here is the condition:
if(description==name) { //country name should be displayed) }
if(description==capital) { //the capital name should be displayed }
How do I do this using twig?
I haven't tried coz I had no idea. Can anyone give me solution for this?

Here is the twig code.
{% if country.field_description.value == 'name' %}
{{ country.title.value }}
{% elseif country.field_description.value == 'capital' %}
{{ country.field_capital.value }}
{% endif %}

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

Looping through values in twig and replacing empty values

The title is a bit ambiguous I know, but let me explain what I'm trying to achieve.
I am attempting to generate a CSV based on data pulled from a doctrine query in my Symfony2 CRM. The data retrieved is based on OpenCart Product and Attribute data, as well as some bespoke information which is irrelevant for this issue.
Each product can have up to 5 different attribute values, named A, B, D, L1 and L2. However, some products do not have all of them, only A, B and L1. The CSV requires each attribute value to be in a separate cell - so the headers are as follows:
ATTRIBUTE: A | ATTRIBUTE: B | ATTRIBUTE: D | ATTRIBUTE: L1 |
ATTRIBUTE: L2
And then I loop through in my Twig file as follows:
{% for attribute in row.product.attributes %}
{% if attribute.text is not null %}
{{ attribute.text }},
{% else %}na,{% endif %}
{% endfor %}
If the product has all 5 attributes, the structure of the CSV is fine. However, if the product only has 3 attributes, it means that all of the subsequent values are pulled back a cell, meaning that the other data is under the wrong headings. I tried checking for values first:
{% for attribute in row.product.attributes %}
{% if attribute.attributeName.name == "A" %}
{% if attribute.text is not null %}
{{ attribute.text }},
{% else %}na,{% endif %}
{% endif %}
{% endfor %}
And I did this for each possible attribute name, but unfortuantely this does not work since if the name does not exist, it just skips it anyway. I'm having trouble trying to think of a way to loop through these attributes and entering a n/a if it's non existent - I'm sure there is a way but I don't know what it is.
For reference, here is the controller code that's generating the data for the CSV:
public function adminCsvAction($filter) {
$repository = $this->getDoctrine()->getRepository('AppBundle:Project');
$stages_repository = $this->getDoctrine()->getRepository('AppBundle:Stage');
$users_repository = $this->getDoctrine()->getRepository('AppBundle:User');
$results = $repository->getSearchResults($filter);
$users = $users_repository->findAll();
$stages = $stages_repository->findBy(array('deleted' => 0), array('sortOrder' => 'ASC'));
$filename = "export_".date("Y_m_d_His").".csv";
$response = $this->render('AppBundle:pages:csv.html.twig', array('data' => $results,'users' => $users, 'stages' => $stages));
$response->headers->set('Content-Type', 'text/csv');
$response->headers->set('Content-Disposition', 'attachment; filename='.$filename);
return $response;
}
The Project Entity has various mappings, one of which links to the Product table in OpenCart which means all attributes and linked values are accessible via this.
Any help in this is much appreciated.
I also agree with Cerad from comment section - that is not the job for Twig. In case your really need to do it, I would try roughly something like this:
{% set allAttr = ["A","B","D","L1","L2"] %}
{% for attribute in allAttr %}
{% if row.product.attributes[attribute] is defined %}
{{ row.product.attributes[attribute].text }}
{% endif %}
{% if not loop.last %},{% endif %}
{% endfor %}
I guess the is defined is critical here...
OK I figured it out. Using what Jovan Perovic suggested, I came up with this:
{% set allAttr = ["A","B","D","L1","L2"] %}
{% set prodAtts = [] %}
{% for row in data %}
{% set existingAtts = [] %}
{% for att in allAttr %}
{% if att not in prodAtts %}
{% set prodAtts = prodAtts|merge([att]) %}
{% endif %}
{% endfor %}
{% for rowAtt in row.product.attributes %}
{% set existingAtts = existingAtts|merge({(rowAtt.attributeName.name|trim):(rowAtt.attributeName.name|trim~'_'~rowAtt.text|trim)}) %}
{% endfor %}
{% for prodAtt in prodAtts %}
{% if prodAtt not in existingAtts|keys %}
{% set existingAtts = existingAtts|merge({(prodAtt):(prodAtt~'_na')}) %}
{% endif %}
{% endfor %}
{% set orderedAtts = existingAtts|sort %}
....
Then the loop for each row thereafter. I used the attribute name with an underscore in order to be able to sort it correct (as it only sorts by value not key) then used preg_replace to remove it along with any instance of the name so I just ended up with the value.
Bit of a lengthy - and probably over thought - solution but it does work!

Symfony2 Twig Conditional Template Name

I'm looking for a way to check in my twig template if the name of the template contains a special word. If that is the case I want to proceed with assigning some stuff. Here is a general idea I have in mind.
{% if [sth like app.request.template_name or sth like that] in `product` %}
// Do some stuff
{% endif % }
Can you guys help me with this?
If you're creating separate template files then you'll know the names and can hardcode the values:
template_1.html.twig:
{% set some_var = 1 %}
{% set another_var = 2 %}
template_2.html.twig:
{% set custom_var = 5 %}
Update:
If you want the template name, you can use:
{% if 'product' in _self.getTemplateName() %}
{# Do stuff #}
{% endif %}

Phalcon count in volt

I have a counting problem in phalcon volt. I have a table named category and there I have two columns id and cname, and also have a table blog and there is a column category. I want to show how many post have in each category.
When I insert a post into blog table, in category column I'm inserting its category id. First of I just retrieve list of all category like this:
[controller]
$categories = Category::find();
$this->view->setVar('category', $categories);
$cx = Blogs::find();
$this->view->setVar('cates',$cx);
[Volt]
{% for categories in category %}
<a href="blog/category/{{categories.cname}}" class="tags">{{ categories.cname }}
<span>[
{% for cx in cates %}
{%if cx.category === categories.id %}
<?php echo(count($cx->category)); ?>
{% endif %}
{% endfor %}
]</span></a>
{% endfor %}
Its render like "1 1 1" or "1 1" or "1" but it should render like "3" or "2" or "1" whats my wrong?
I also tried like this but did not get the expected output:
{% for categories in category %}
<a href="blog/category/{{categories.cname}}" class="tags">{{ categories.cname }}
<span>[
{% for cx in cates %}
{%if cx.category === categories.id %}
{% if loop.first %} {{ loop.length }} {% endif %}
{% endif %}
{% endfor %}
]</span></a>
{% endfor %}
Have you defined your relationships between your models in Phalcon?
If so, you can use the built in commands to query the total amount of posts for each category
Example from the documentation:
You can also use “count” prefix to return an integer denoting the count of the related records:
$robot = Robots::findFirst(2);
echo "The robot has ", $robot->countRobotsParts(), " parts\n";
I don't have much experience with Volt templating, but I guess it will be something like:
{% for categories in category %}
<a href="blog/category/{{categories.cname}}" class="tags">{{ categories.cname }}
<span>[
{{ categories.countBlogs }}
]</span></a>
{% endfor %}
Refer to: https://docs.phalconphp.com/en/latest/reference/models.html#taking-advantage-of-relationships
UPDATE - model relations
[model: Category]
public function initialize()
{
// id => primary key name of the Category table
// Blogs => name of the table you want to create a relationship with
// category => name of the foreign key column in your relationship table
$this->hasMany('id', 'Blogs', 'category');
}
[model: Blogs]
public function initialize()
{
// category => blog column name which refers to the ID in the Category table
// Category => name of the Category table
// id => name of the primary key column in the Category table
$this->belongsTo('category', 'Category', 'id');
}
No Sir, its not working. But i just solved my problem like this :
[controller]
$categories = Category::find();
$this->view->setVar('category', $categories);
[volt]
{% for categories in category %}
<a href="blog/category/{{categories.cname}}" class="tags">{{ categories.cname }}
<span>[
<?php
$catcount = $this->modelsManager->executeQuery("SELECT Blogs.category FROM Blogs WHERE Blogs.category = $categories->id");echo(count($catcount));
?>
]</span></a>
{% endfor %}
Now its working as expected. and here i dont make any relations ion model.Is it ok Sir. Please! Thnx

compare a input field value to a string or text symfony2

I was trying to learn about framework and Ill be starting under "Symfony", then i got this problem, I create a
{{ form_widget(form.type) }}
equivalent to
<input type="text" class="type" id="type"/>
this element "input" have a value that given by a tab or menu if i click on it, example jumping.how do i compare it to a text using "Symfony" if statement like the logic below.
{% if jumping == "text" %}
//it will do something
{% endif %}
as explained nicely in the symfony docs here you need to use the form.vars.value to get the input field's value
so for someting like {{ form_widget(form.name) }} you would access the values by doing {{ form.vars.value.name }}
in your case it would be
{% if form.vars.value.name == "text" %}
//do something
{% endif %}

Resources