我想覆盖我的表单部分的渲染方式,但我总是忘记 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 名称连接在一起。对于
SetPasswordType
的widget
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/