Symfony可让您轻松customize, extend, or create your own form type widgets。如果要将新表单类型命名为“foo”,则此方法很有用。但是,如果您想使用两个字命名自定义类型,例如fooBar
,那么您将如何命名PHP formType,服务和Twig?有很多symfony核心表单类型的例子,它们是由下划线分隔的多个单词,例如: collection_item_widget
。但这对自定义表单类型不起作用。
因此,如果您想创建一个名为fooBarType
的新表单类型,您将创建一个名为fooBarType.php
的控制器
class FooBarType extends AbstractType {
public function getName() {
return 'fooBar';
}
public function getParent() {
return 'form';
}
}
将此项设为服务(可选):
cms.form.type.foo_bar:
class: Cms\FooBundle\Form\Type\FooBar
tags:
- { name: form.type, alias: fooBar }
然后自定义fields.html.twig
并为名为foo_bar_widget
或foobar_widget
或fooBar_widget
创建一个块(这些都不起作用):
{% block foo_bar_widget %}
{{ block('entity_widget') }}
{% endblock %}
注意:如果它位于不同的位置,您还必须在config.yml中注册
twig:
form:
resources:
- 'CmsFooBundle:Form:fields.html.twig'
然后在表单构建器中使用该字段,例如
$builder->add('myField', 'fooBar');
一切都在上面工作,除了fields.html.twig中的自定义块不呈现,除非我将所有名称更改为像'foo'这样简单的名称。
¿Por Que?
答案 0 :(得分:2)
我的例子的问题在于从服务定义开始的camelCase的不一致性,以及树枝模板中的问题。
从技术上讲,根据规范,服务应该是小写和下划线,例如cms.form.type.foo_bar
。并且枝条小部件定义也是下划线,例如collection_item_widget
。因此,尽管camelCase和下划线工作(如果你在widget中是一致的,formType控制器的getName(),以及$ formBuilder-> add()函数),它应该总是下划线。
现在这对我有用:
控制器
class FooBarType extends AbstractType {
public function getName() {
return 'foo_bar';
}
public function getParent() {
return 'form';
}
}
服务定义
cms.form.type.foo_bar:
class: Cms\FooBundle\Form\Type\FooBar
tags:
- { name: form.type, alias: foo_bar }
表单构建器中的用法
$builder->add('myField', 'foo_bar');
fields.html.twig
fields.html.twig可以定义为camelCase(以匹配别名)。但显然没有block('entity_widget')
这样的事情。我认为实体只是选择小部件的扩展。所以我的自定义小部件正在加载,但没有选择,因为该块不正确。如果我将其更改为choice_widget
:
{% block foo_bar_widget %}
<!-- some customizations -->
{{ block('choice_widget') }}
{% endblock %}
答案 1 :(得分:1)
前面的说明:如果您没有任何参数或其他服务需要注入该类型,则不必将表单类型定义为服务。您始终可以通过以下方式直接在表单构建器中调用表单类型:
$builder
->add('foo_bar_field', new FooBarType());
无论如何,我只是使用documentation中的性别类型示例进行了快速测试,它对我来说很好。
这些是我使用的设置:
输入类 Jahller \ TestBundle \ Form \ Type \ GenderDoType.php
namespace Jahller\TestBundle\Form\Type;
// ...
class GenderDoType extends AbstractType
{
// ...
public function getParent()
{
return 'choice';
}
public function getName()
{
return 'genderDo';
}
}
服务定义 Jahller / TestBundle / Resources / config / services.yml
jahller.form.type.gender:
class: Jahller\TestBundle\Form\Type\GenderDoType
tags:
- { name: form.type, alias: genderDo }
键入树枝模板 Jahller / TestBundle / Resources / views / Form / fields.html.twig
{% block genderDo_widget %}
{% spaceless %}
{% if expanded %}
<ul {{ block('widget_container_attributes') }}>
{% for child in form %}
<li>
{{ form_widget(child) }}
{{ form_label(child) }}
</li>
{% endfor %}
</ul>
{% else %}
{# just let the choice widget render the select tag #}
{{ block('choice_widget') }}
{% endif %}
{% endspaceless %}
{% endblock %}
类型包含 Jahller \ TestBundle \ Form \ TestType.php
的表单类namespace Jahller\TestBundle\Form;
// ...
class TestType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('gender_code', 'genderDo', array(
'placeholder' => 'Choose a gender',
));
}
public function configureOptions(OptionsResolver $resolver)
{
// ...
}
public function getName()
{
return 'test';
}
}
渲染类型:
也许你可以在我的代码中找到你做的不同的事情。