Symfony中如何为EasyAdmin编辑页自定义字段覆盖模板
问题:EasyAdmin自定义TranslationField编辑页不加载自定义模板
我用A2lix翻译组件和EasyAdmin做了个自定义字段TranslationField,指定模板admin/field/translation_field.html.twig实现语言标签页功能。实体详情页能正常加载这个自定义模板,但进入编辑页时,系统却用EasyAdmin默认字段模板,语言标签页无法显示。
解决思路
EasyAdmin中字段模板分为详情页模板和表单页(编辑/新建)模板两类,当前仅配置了通用模板,表单场景下会优先使用表单主题渲染,而非自定义字段模板。需要区分页面场景调整配置,同时适配模板的渲染逻辑。
具体修复步骤
1. 修改自定义TranslationField类
核心是为表单页指定表单主题,同时保留详情页的模板配置:
<?php declare(strict_types=1); namespace App\Controller\Admin\Field; use A2lix\TranslationFormBundle\Form\Type\TranslationsType; use EasyCorp\Bundle\EasyAdminBundle\Contracts\Field\FieldInterface; use EasyCorp\Bundle\EasyAdminBundle\Field\FieldTrait; final class TranslationField implements FieldInterface { use FieldTrait; public static function new(string $propertyName, ?string $label = null, array $fieldsConfig = []): self { $field = (new self()) ->setProperty($propertyName) ->setLabel($label) ->setFormType(TranslationsType::class) ->setFormTypeOptions([ 'default_locale' => 'fr', 'fields' => $fieldsConfig, // 为表单页绑定自定义模板作为表单主题 'attr' => [ 'form_theme' => 'admin/field/translation_field.html.twig', ], ]); // 单独为详情页设置模板 $field->setTemplatePath('admin/field/translation_field.html.twig') ->setTemplateName('translation_field'); return $field; } }
2. 调整Twig模板适配双场景
修改模板,判断当前页面类型,分别渲染详情页和表单页的内容:
{# @var ea \EasyCorp\Bundle\EasyAdminBundle\Context\AdminContext #} {# @var field \EasyCorp\Bundle\EasyAdminBundle\Dto\FieldDto #} {# @var entity \EasyCorp\Bundle\EasyAdminBundle\Dto\EntityDto #} {% set render_as_html = field.customOptions.get('renderAsHtml') %} {% set isFormPage = ea.crud.currentPage in ['new', 'edit'] %} {% if isFormPage %} {# 编辑/新建页:渲染带标签页的表单字段 #} <div class="data-row"> <ul class="nav nav-tabs w-100 border-bottom-0" role="tablist"> {% for locale in field.formTypeOptions.fields.name.locale_options|keys %} <li class="nav-item" role="presentation"> <a id="{{ locale|upper }}-tab" data-bs-toggle="pill" data-bs-target="#{{ locale|upper }}-content" class="border-bottom nav-link{% if locale == app.request.locale %} active{% endif %}" href="#" role="tab"> {{ locale|upper }} </a> </li> {% endfor %} </ul> <div class="tab-content p-3 border"> {% for locale in field.formTypeOptions.fields.name.locale_options|keys %} <div id="{{ locale|upper }}-content" class="tab-pane fade{% if locale == app.request.locale %} show active{% endif %}" role="tabpanel"> {{ form_widget(form.translations[locale].name) }} </div> {% endfor %} </div> </div> {% else %} {# 详情页:原有标签页渲染逻辑 #} </dd></div></dl> <div class="data-row"> <ul class="nav nav-tabs w-100 border-bottom-0" role="tablist"> {% set myArray = field.value|toArray %} {% for key_langue, valueObject in myArray['collection'] %} <li class="nav-item" role="presentation"> <a id="{{ key_langue|upper }}-home-tab" data-bs-toggle="pill" data-bs-target="#{{ key_langue|upper }}-home" class="border-bottom nav-link{% if key_langue == app.request.locale %} active{% endif %}" href="#{{ key_langue }}-tab" aria-controls="{{ key_langue }}-tab" role="tab" data-toggle="tab"> {{ key_langue|upper }} </a> </li> {% endfor %} </ul> {# 原有详情页内容渲染部分 #} [...] </div> {% endif %}
3. 在CrudController中加载自定义表单主题
确保自定义模板被注册为表单主题:
public function configureCrud(Crud $crud): Crud { return $crud ->setEntityLabelInSingular('Product') ->setEntityLabelInPlural('Products') ->setPageTitle("index", "Admin product") ->setPaginatorPageSize(20) ->addFormTheme('@FOSCKEditor/Form/ckeditor_widget.html.twig') ->addFormTheme('admin/field/translation_field.html.twig'); // 添加这一行 }
关键原因
EasyAdmin的setTemplatePath方法主要用于详情页(show)的渲染,而编辑/新建页的字段渲染依赖Symfony表单主题机制,默认会使用EasyAdmin内置表单模板或字段关联FormType的自带模板。因此必须通过表单主题覆盖编辑页的渲染逻辑,同时区分场景编写模板代码。
内容的提问来源于stack exchange,提问作者Lionel
相关产品推荐
相关产品推荐

