SonataAdmin - 如何在显示特定操作链接之前添加自定义逻辑

SonataAdmin - How to add custom logic before displaying specific actions links

我知道我们可以在实体管理员的视图列表中自定义我们想要的操作链接 class 感谢:

$listMapper
    ->addIdentifier('name')
    ->add('minRole')
    ->add('_action', null, [
        'actions' => [
            'show' => [],
            'edit' => [],
            'delete' => []
        ]
    ])
;

或通过服务管理角色:sonata.admin.security.handler.role

在我的例子中,我想添加一个域逻辑以显示或不显示删除按钮(它出现在 视图列表编辑查看).

{% if attribute(object, hasEvents) is defined and not object.hasEvents %}
   # display it
{% endif %}

我不知道如何重写奏鸣曲的树枝模板才能做到这一点。只涉及两个实体:EventPost.

编辑

对于视图列表我直接覆盖了list__action_delete.html.twig模板(我创建了app/Resources/SonataAdminBundle/views/CRUD/list__action_delete.html.twig)这是代码(我知道这不是最好的方式...):

{#

The template override the basic one in order to prevent the display of the delete button (in the view list) for the entities
Post and Event. We only display it if they don't have associated activities.

#}
{% if admin.isGranted('DELETE', object) and admin.hasRoute('delete') %}
    {% if not attribute(object, 'isDeleteable') is defined %}
        <a href="{{ admin.generateObjectUrl('delete', object) }}" class="btn btn-sm btn-default delete_link" title="{{ 'action_delete'|trans({}, 'SonataAdminBundle') }}">
            <i class="fa fa-times"></i>
            {{ 'action_delete'|trans({}, 'SonataAdminBundle') }}
        </a>
    {% else %}
        {% if object.isDeleteable %}
            <a href="{{ admin.generateObjectUrl('delete', object) }}" class="btn btn-sm btn-default delete_link" title="{{ 'action_delete'|trans({}, 'SonataAdminBundle') }}">
                <i class="fa fa-times"></i>
                {{ 'action_delete'|trans({}, 'SonataAdminBundle') }}
            </a>
        {% endif %}
    {% endif %}
{% endif %}

我将以编辑模板为例向您展示一个解决方案。您应该按照相同的方法搜索要覆盖的任何其他部件/块/模板。

您要做的是覆盖/扩展编辑模板的 formactions 块。该块在奏鸣曲管理包的 base_edit_form.html.twig 模板中定义:

vendor/sonata-project/admin-bundle/Resources/views/CRUD/base_edit_form.html.twig

要覆盖模板,有不同的方法。您可以使用 symfony doc about how to override any part of a bundle or you can use the config options to override the path for some of the sonata templates as described in the docs.

中描述的方法

我推荐使用后者。假设您有一个 AppBundle 并且想用它来覆盖模板。将这些行添加到 app/config/config.yml 文件中的奏鸣曲配置部分:

sonata_admin:
    templates:
        edit: AppBundle:CRUD:edit.html.twig

创建文件 src/AppBundle/Resources/views/CRUD/edit.html.twig 并复制 formactionsvendor/sonata-project/admin-bundle/Resources/views/CRUD/base_edit_form.html.twig模板进去。不要忘记扩展奏鸣曲捆绑包附带的 base_edit.html.twig 模板(第一行):

{% extends 'SonataAdminBundle:CRUD:base_list.html.twig' %}

{% block formactions %}
    ...
{% endblock formactions %}

formactions 块中找到删除按钮,然后添加您的自定义 if 语句以执行您想要执行的任何操作。