I would like to be able to override some default templates per entity module. For instance, I need to access and override the template that renders the actions for each object in the list view. For some of my entities, some of the actions should not be displayed if some conditions are not met.
For instance, I've an entity model called Product. Each instance of Product has a publication status field whose value can be either DRAFT, REVIEW or PUBLISHED. I would like to discard the delete action for the objects that have a PUBLISHED status. Once the object is live it cannot be deleted anymore.
This could be solved in many different ways I think.
In the actions template, I would like to be able to do something like this:
{% if 'delete' === action and item.deletable %}
... display delete link ...
{% endif %}
To achieve that, we just need to easily fix the list.html.twig template that includes the actions.html.twig template. The include() statement can accept an array of file paths. The first that matches wins:
...
{% if _list_item_actions|length > 0 %}
{% set _column_label = 'list.row_actions'|trans(_trans_parameters, 'EasyAdminBundle') %}
<td data-label="{{ _column_label }}" class="actions">
{% block item_actions %}
{{ include(["@EasyAdmin/#{ENTITY_NAME}/includes/_actions.html.twig", '@EasyAdmin/default/includes/_actions.html.twig'], {
actions: _list_item_actions,
request_parameters: _request_parameters,
trans_parameters: _trans_parameters,
item_id: _item_id,
item: item
}, with_context = false) }}
{% endblock item_actions %}
</td>
{% endif %}
...
This time, the current item variable must be passed to the actions template in order to be able to use it.
We could use the expression language directly in the config with something like that:
easy_admin:
entities:
Product:
list:
actions:
- new
- edit
- { name: delete, condition: 'item.isDeletable()' }
This makes it simple!
easy_admin:
entities:
Product:
list:
actions: [new, edit, delete]
templates:
actions:
template: 'foo/bar/_actions.html.twig'
context: { foo: bar, baz: '%qux%' }
What do you think?
EasyAdminBundle already provides a way to override templates per entity. But it's unfortunately not available for the _actions.html.twig template :/
So what about adding it (with other included templates) in the TemplateConfigPass and using it in the list.html.twig one ?
@javiereguiluz any comments from you please?
I have two quick comments:
1) The _actions.html.twig template is just a fragment that we use internally to avoid template repetition. But it's not a real template and that's why it's not exposed publicly or documented.
2) Currently we allow to override templates by configuration or by convention. For example, by convention you could create this file in this location to override the list.html.twig template for some entities:
{# app/Resources/views/easy_admin/<ENTITY NAME>/list.html.twig #}
{% extends '@EasyAdmin/default/list.html.twig' %}
{% block item_actions %}
{# here do something with the '_list_item_actions' variable to
add or remove actions depending on some conditions #}
{{ parent() }}
{% endblock item_actions %}
If the logic is similar or identical for several entities, you can again override the template for all entities by configuration or by convention (creating instead the app/Resources/views/easy_admin/list.html.twig file).
Would this comment help you solve this issue?
Thanks Javier for the explanations. I helps but that means I'll probably have lots of repetitions in the end. I just need to be able to display or not the actions links based on some conditions.
I've tested this template in the EasyAdmin Demo application and it works as expected. It would require you to create just 1 file to manage all those common entities:
{# app/Resources/views/easy_admin/list.html.twig #}
{% extends '@EasyAdmin/default/list.html.twig' %}
{% block item_actions %}
{% if _entity_config.name in ['Product', 'Article', 'Page'] %}
{% set filtered_actions = {} %}
{% for action_name, action_config in _list_item_actions %}
{% if action_name == 'delete' and item.publication|default(false) == 'PUBLISHED' %}
{# remove the 'delete' action from published items #}
{% else %}
{% set filtered_actions = filtered_actions|merge([action_config]) %}
{% endif %}
{% endfor %}
{% set _list_item_actions = filtered_actions %}
{% endif %}
{{ parent() }}
{% endblock item_actions %}
Thanks for the hint ;)
This is really good. I hacked away at _actions.twig.html to achieve this. I think, before closing this, it would be great if we can have this snippet in the tutorials.
Closing this as "fixed" ... and added the tip about dynamic item actions in #1264. Thanks!
Hello, @javiereguiluz , how we can apply the same scenario for the edit template , because i've tried it and i cant access the _list_item_actions :/
+1 for the Edit support, i'm struggling trying to edit action template and rendering
Most helpful comment
I've tested this template in the EasyAdmin Demo application and it works as expected. It would require you to create just 1 file to manage all those common entities: