symfony - 查找/自定义 Symfony Forms Twig block 名称

标签 symfony twig symfony-forms

我想覆盖我的表单部分的渲染方式,但我总是忘记 symfony 表单渲染哪些 Twig block 名称。如果没有找到该 block ,我不会得到任何反馈,为什么没有找到,以及应该如何调用它。

示例:

class SetPasswordType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('plainPassword', PasswordType::class);
        $builder->add('repeatPlainPassword', PasswordType::class);
    }
}

三个基本问题:

  • symfony 表单如何确定 SetPasswordType 的 Twig block 名称?
  • 如何查找此信息?
  • 我如何自定义它?

最佳答案

对于此特定类型,twig widget block 名称为 set_password_widget

在表单主题中覆盖它,如下所示:

{% block set_password_widget %}
    <div class="row">
        <div class="col">
            {{ form_row(form.plainPassword) }}
        </div>
        <div class="col">
            {{ form_row(form.repeatPlainPassword) }}
        </div>
    </div>
{% endblock %}

如何覆盖 block

  • 确定 block 前缀,默认情况下取决于类名。对于SetPasswordType,它是set_password
  • 决定要渲染哪个 block 。如果您想更改布局,您可能会覆盖 row block 。如果您想更改输入,您可能会覆盖 widget block 。引用文档:https://symfony.com/doc/current/form/form_themes.html#form-fragment-naming
  • 将 block 前缀和 block 名称连接在一起。对于 SetPasswordTypewidget block ,您需要覆盖 set_password_widget
  • 将 Twig block 放入表单主题中。

覆盖失败时进行故障排除

  • 检查 twig block 是否位于 twig.form_themes 中配置的文件中或作为表单主题包含在内。
  • 检查 Symfony\Component\Form\Extension\Core\Type\BaseType::buildView 中的 $blockPrefixes 以查看确定了哪些 block 前缀。将首先查找数组中的最后一个条目。
  • 检查 Symfony\Component\Form\FormRenderer::searchAndRenderBlock 中的 $blockNameHierarchy 以查看要查找哪些特定 block 。将首先查找数组中的最后一个条目。

详细演练

block 的名称在 Symfony\Component\Form\Extension\Core\Type\BaseType::buildView 中的 $blockPrefixes 变量中构建。 $blockPrefixes 定义以下优先级(首先提到的 = 最高优先级。它是反向存储的!):

  • 唯一的 block 名称(根据属性名称分层构建)。
  • block 前缀(如果已配置)
  • 类型的名称(如果继承自 AbstractType,则名称在 AbstractType::getBlockPrefix() 中生成)
  • 所有父类型的名称(遵循 FormTypeInterface::getParent() 方法链)。

例如,它可能如下所示:

$blockPrefixes = [
  0 => "form", # because `AbstractType::getParent()` returns `FormType`
  1 => "set_password", # our type, name resolved automatically depending on class name 

  ## at this position, a block prefix would be included if one is configured 

  2 => "_set_password" # the hierarchical unique name, prefixed with `_`. for the plainPassword field, this value would be "searchAndRenderBlock". 
];

当表单由 twig 渲染时,将使用相应的 $blockNameSuffix 调用 Symfony\Component\Form\FormRenderer::searchAndRenderBlock (例如 widget )。 $blockNameHierarchy 是通过在每个潜在前缀后添加 $blockNameSuffix 来创建的。

对于 $blockNameSuffix == "row" ,它看起来像这样:

$blockNameHierarchy = [
  0 => "form_widget",
  1 => "set_password_widget",
  2 => "_set_password_widget"];

查找这些 block ,并选择可以找到的具有最高优先级的 block 。数组中越靠后的优先级越高。

自定义 block 前缀

您可以像这样自定义前缀:

class SetPasswordType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('plainPassword', PasswordType::class, ['mapped' => false]);
        $builder->add('repeatPlainPassword', PasswordType::class, ['mapped' => false]);
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefault('block_prefix', 'my_custom_prefix');
        $resolver->setDefault('block_name', 'my_custom_name');
    }
}

这将导致

$blockPrefixes = [
  0 => "form", 
  1 => "set_password", # this will stay the same as its resolved depending on type name

  2 => "my_custom_prefix", # as per our configuration, we now have a custom prefix

  3 => "_my_custom_name" # the custom name will be used to determine the hierarchical name
];

关于symfony - 查找/自定义 Symfony Forms Twig block 名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64679231/

相关文章:

php - "Access Denied Code 5"Symfony2/Doctrine2 PHP重命名错误

php - Symfony 4多重保护验证器重定向问题

Twig IF 语句不起作用

php - 我如何检测表单是否有任何要呈现的元素?

php - 验证用户是否在 symfony2 中通过身份验证

symfony - CORS Api 与 symfony

symfony - 如何通过实体管理器获取上一个和下一个实体

javascript - Twig JS 内联模板无法解析

symfony - 新版Sonata Admin如何覆盖 'show'模板

php - 无法从表单类型的查询构建器函数访问全局变量