I would like to implement while(true) in twig. I wonder how to implement the below logic
while(true){
/* Do something */
if(/*some condition met */){
break;
}
}
in twig?
I've not testet this, but something this way may produce an infinitive loop.
{% macro while() %}
{% import _self as self %}
{% if not /*some condition met */ %}
{{ self.while() }}
{% endif %}
{% endmacro %}
Related
I have a logic that wouldn't be easy to implement in EasyAdmin so I decided that I implement it in Symfony 6 then integrate it into EA. The integration worked like a charm but I can't figure out which form_theme should I use to look like the other EA forms.
I have created a form type which doesn't belong to any entity since multiple entities will be generated after the validation based on the input data.
This is the controller
<?php
namespace App\Controller\Admin;
use App\Form\Type\NewTextType;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class TextController extends AbstractController
{
#[Route('/admin/text/new', name: 'new_text')]
public function new(): Response
{
$defaultData = [];
$form = $this->createForm(NewTextType::class, $defaultData);
if ($form->isSubmitted() && $form->isValid()) {
$data = $form->getData();
// process the data and persist them as different entities
// redirect to the empty form and do it again
}
return $this->renderForm('admin/text/new.html.twig', [
'form' => $form,
]);
}
}
and the template
{% extends '#EasyAdmin/page/content.html.twig' %}
{% form_theme form 'foundation_5_layout.html.twig' %}
{% block content_title %}
<h1 class="title">Add new Text</h1>
{% endblock %}
{% block main %}
{{ form(form) }}
{% endblock %}
Unfortunately it looks like a crap.
It looks better if I replace foundation_5_layout with {% form_theme form 'bootstrap_5_layout.html.twig' %} but then the appearance setting is not applied even though it is presented in the BODY tag:
data-ea-dark-scheme-is-enabled="true"
What do I miss here?
I use Symfony 6.1.2 and EasyAdmin 4.3.2
Finally I have found the right template which supports the Light/Dark appearance:
{% form_theme form '#EasyAdmin/crud/form_theme.html.twig' %}
The whole template
{% extends '#EasyAdmin/page/content.html.twig' %}
{% form_theme form '#EasyAdmin/crud/form_theme.html.twig' %}
{% block content_title %}
<h1 class="title">Add new Text</h1>
{% endblock %}
{% block main %}
{{ form(form) }}
{% endblock %}
I have Shopware 6.5.3. I was trying to extend "sw-users-permissions-user-detail" like this :
import template from './sw-users-permissions-user-detail.html.twig';
Shopware.Component.override('sw-users-permissions-user-detail', {
template
});
And file 'sw-users-permissions-user-detail.html.twig'
{% block sw_settings_user_detail %}
{% parent %}
{% block test %}
<p>Blabla</p>
{% endblock %}
{% endblock %}
It's not working at all, and I don't know why.
Any help ?
NB : It's working when I'm overriding other templates :
Component.override('sw-dashboard-index', {
template
});
If you want to put the original contents to the block, that you are overriding, you should use the 'parent' statement like this:
{{ parent() }}
I'm trying to check in twig if any element of one array are set in other array.
Example:
I have user.roles with ['ROLE_ADMIN','ROLE_MANAGER'] and I have the product.roles with ['ROLE_ADMIN','ROLE_USER'].
I want to check (in Twig) if any user.roles are in product.roles, like:
{{ user.roles[0] is product.roles|keys }}
But with each element of user.roles in the same function.
Does anyone know how?
You could use the filter filter to do this, but guessing it would be better to move this to PHP / TwigExtension
{% if user.roles |filter((role) => role in product.roles) | length > 0 %}
Can do something with the post
{% else %}
Access denied
{% endif %}
demo
Use a for loop:
{% for role in user.roles %}
{% if role in product.roles|keys %}
do something...
{% endif %}
{% endfor %}
One question please.
{{ dump(app.user.slugName) }}
If I do the above snippet in Twig, I get the slugName of the user loged ("my-user-2", i.e.) in the app (SlugName is an atribute of the entity user). Ok & Correct. But... I want to order this action from a var (var from BD data)
I have a variable named option which is set like this:
{% set option = 'app.user.slugName' %}
But when I'm trying output this variable with {{ dump(option)}} it returns app.user.slugName as literal. It does not return my-user-2.
Is there are any way in twig to solve this? It's a function to generate a menu, but some links needs some parameters.
I see what you mean, but Twig can't evaluate expression like that.
To achieve something like that you would need a snippet like this,
{% set value_methods = 'app.user.slugname' %}
{% set option_value = _context %}
{% for method in (value_methods|split('.')) if method != '' %}
{% set option_value = attribute(option_value, (method|replace({'()': '', }))) %}
{% endfor %}
{{ option_value }}
twigfiddle
(edit)
Remember you can create a macro to achieve some reusability for this snippet,
{% import _self as macros %}
{{ macros.evaluate(_context, 'app.user.slugname') }}
{% macro evaluate(context, value_methods) %}
{% set option_value = context %}
{% for method in (value_methods|split('.')) if method != '' %}
{% set option_value = attribute(option_value, (method|replace({'()': '', }))) %}
{% endfor %}
{{ option_value }}
{% endmacro %}
Is it possible to check if given variable is string in Twig ?
Expected solution:
messages.en.yml:
hello:
stranger: Hello stranger !
known: Hello %name% !
Twig template:
{% set title='hello.stranger' %}
{% set title=['hello.known',{'%name%' : 'hsz'}] %}
{% if title is string %}
{{ title|trans }}
{% else %}
{{ title[0]|trans(title[1]) }}
{% endif %}
Is it possible to do it this way ? Or maybe you have better solution ?
Can be done with the test iterable, added in twig1.7, as Wouter J stated in the comment :
{# evaluates to true if the users variable is iterable #}
{% if users is iterable %}
{% for user in users %}
Hello {{ user }}!
{% endfor %}
{% else %}
{# users is probably a string #}
Hello {{ users }}!
{% endif %}
Reference : iterable
Ok, I did it with:
{% if title[0] is not defined %}
{{ title|trans }}
{% else %}
{{ title[0]|trans(title[1]) }}
{% endif %}
Ugly, but works.
I found iterable to not be good enough since other objects can also be iterable, and are clearly different than an array.
Therefore adding a new Twig_SimpleTest to check if an item is_array is much more explicit. You can add this to your app configuration / after twig is bootstrapped.
$isArray= new Twig_SimpleTest('array', function ($value) {
return is_array($value);
});
$twig->addTest($isArray);
Usage becomes very clean:
{% if value is array %}
<!-- handle array -->
{% else %}
<!-- handle non-array -->
{% endif % }
There is no way to check it correctly using code from the box.
It's better to create custom TwigExtension and add custom check (or use code from OptionResolver).
So, as the result, for Twig 3, it will be smth like this
class CoreExtension extends AbstractExtension
{
public function getTests(): array
{
return [
new TwigTest('instanceof', [$this, 'instanceof']),
];
}
public function instanceof($value, string $type): bool
{
return ('null' === $type && null === $value)
|| (\function_exists($func = 'is_'.$type) && $func($value))
|| $value instanceof $type;
}
}
Assuming you know for a fact that a value is always either a string or an array:
{% if value is iterable and value is not string %}
...
{% else %}
...
{% endif %}
This worked good enough for me in a project I was working on. I realize you may need another solution.