如何在 Twig 中将实体(选择 <select>)字段呈现为 <ul> 字段?
How can I render an entity (choice <select>) field as a <ul> field in Twig?
Symfony renders an entity
field type like a choice
dropdown - a select
, basically. However, the CSS framework that I'm using defines a sort of 'select' as a ul
and li
as the options. The Custom Field Type documentation gives no help on this scenario.
我正在将我的代码从手动 HTML 呈现表单下拉列表转换为使用 twig 和 form_widget()
的 symfony 表单版本。但是,我想要 ul
和 li
而不是 select
.
创建下拉菜单的手动方法是:
<ul class='dropdown-menu'>
{% for locator in locators %}
<li>
<a href="#" data-id="{{locator.getId() }}">
{{ locator.getName() }}
</a>
</li>
{% endfor %}
</ul>
这就是我在使用 symfony 表单之前手动呈现下拉列表的方式。它看起来像这样:
我喜欢。我觉得它看起来棒极了。现在,如果我使用的是 Symfony 表单,我可以只使用它:
{{ form_start(form) }}
{{ form_widget(form.locator) }} {# This is my locator dropdown #}
{{ form_widget(form.target) }} {# Ignore this #}
{{ form_end(form) }}
问题是这会呈现这个:
我无法在此处添加我的自定义 CSS,因为它呈现为 select
而不是无序列表和 li
s.
如果有帮助,这是我正在构建的表单类型:
/**
* {@inheritDoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('target')
->add('locator', 'entity', [
'class' => 'Application\Model\Entity\Locator',
'query_builder' => function(EntityRepository $repo) {
return $repo->createQueryBuilder('e');
},
'empty_value' => 'Locator'
])
->add('save', 'submit', ['label' => 'Save']);
$builder->setAction($this->urlGenerator->generate('page_create_element', [
'suiteId' => $options['suiteId'], 'pageId' => $options['pageId']
]))->setMethod('POST');
}
问题:有什么方法可以让上面的表单命令自动生成我的 ul / li 要求而不是选择,或者我是否必须手动呈现它并为此忽略 symfony 表单组件?
Thanks to some of the posters above, there was some information from Form Theming, but it wasn't exactly enough to go along with so I had to do a little bit of digging on github.
根据 documentation,Symfony 使用 twig 模板呈现表单的相关位及其包含的元素。这些只是树枝中的 {% block %}
s。所以第一步是找到在 symfony 代码库中呈现 select 按钮的位置。
表单主题
首先,您在自己的 twig 文件中创建自己的主题块,然后使用以下代码将此主题应用于您的表单:
{% form_theme my_form_name 'form/file_to_overridewith.html.twig %}
因此,如果我在上面的文件中覆盖了 {% block form_row %}
,那么当我调用 {{ form_row(form) }}
时,它将使用我的块而不是 Symfony 的默认块。
重要提示:您不必覆盖所有内容。只需覆盖您想要更改的内容,如果在您的主题中找不到任何内容,Symfony 将回退到它自己的块。
源代码
在 github 上,我找到了 Symfony 的 "choice widget" 的 source code。它有点复杂,但如果您按照它进行操作并进行一些实验,您就会明白它的走向。
在 choice_widget_collapsed
块中,我将 select 更改为 ul
,并将选项更改为 li
。这是我创建的主题文件,请注意上面描述的细微差别:
{# Symfony renders a 'choice' or 'entity' field as a select dropdown - this changes it to ul/li's for our own CSS #}
{%- block choice_widget_collapsed -%}
{%- if required and empty_value is none and not empty_value_in_choices and not multiple -%}
{% set required = false %}
{%- endif -%}
<ul {{ block('widget_attributes') }}{% if multiple %} multiple="multiple"{% endif %}>
{%- if preferred_choices|length > 0 -%}
{% set options = preferred_choices %}
{{- block('choice_widget_options') -}}
{%- if choices|length > 0 and separator is not none -%}
<li disabled="disabled">{{ separator }}</li>
{%- endif -%}
{%- endif -%}
{%- set options = choices -%}
{{- block('choice_widget_options') -}}
</ul>
{%- endblock choice_widget_collapsed -%}
{%- block choice_widget_options -%}
{% for group_label, choice in options %}
{%- if choice is iterable -%}
<optgroup label="{{ group_label|trans({}, translation_domain) }}">
{% set options = choice %}
{{- block('choice_widget_options') -}}
</optgroup>
{%- else -%}
<li value="{{ choice.value }}"{% if choice is selectedchoice(value) %} selected="selected"{% endif %}><a href="#">{{ choice.label|trans({}, translation_domain) }}</a></li>
{%- endif -%}
{% endfor %}
{%- endblock choice_widget_options -%}
渲染
现在我可以使用以下内容呈现我的表单:
{{ form_widget(form.locator, {'attr': {'class': 'dropdown-menu'}}) }}
这将我的主题用于选择下拉菜单,其中包含 ul
和 li
标签而不是 select
和 option
标签。一旦您知道在哪里寻找原始代码,就非常简单!呈现的 HTML:
<ul id="elementtype_locator" name="elementtype[locator]" required="required" class="dropdown-menu">
<li value="1"><a href="#">id</a></li>
<li value="2"><a href="#">name</a></li>
<li value="3"><a href="#">xpath</a></li>
</ul>
我还必须删除将 'Locator' 放在下拉列表顶部的行之一,因为有四个下拉选项(包括 empty_data 一个)而不是三个。
Symfony renders an
entity
field type like achoice
dropdown - aselect
, basically. However, the CSS framework that I'm using defines a sort of 'select' as aul
andli
as the options. The Custom Field Type documentation gives no help on this scenario.
我正在将我的代码从手动 HTML 呈现表单下拉列表转换为使用 twig 和 form_widget()
的 symfony 表单版本。但是,我想要 ul
和 li
而不是 select
.
创建下拉菜单的手动方法是:
<ul class='dropdown-menu'>
{% for locator in locators %}
<li>
<a href="#" data-id="{{locator.getId() }}">
{{ locator.getName() }}
</a>
</li>
{% endfor %}
</ul>
这就是我在使用 symfony 表单之前手动呈现下拉列表的方式。它看起来像这样:
我喜欢。我觉得它看起来棒极了。现在,如果我使用的是 Symfony 表单,我可以只使用它:
{{ form_start(form) }}
{{ form_widget(form.locator) }} {# This is my locator dropdown #}
{{ form_widget(form.target) }} {# Ignore this #}
{{ form_end(form) }}
问题是这会呈现这个:
我无法在此处添加我的自定义 CSS,因为它呈现为 select
而不是无序列表和 li
s.
如果有帮助,这是我正在构建的表单类型:
/**
* {@inheritDoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('target')
->add('locator', 'entity', [
'class' => 'Application\Model\Entity\Locator',
'query_builder' => function(EntityRepository $repo) {
return $repo->createQueryBuilder('e');
},
'empty_value' => 'Locator'
])
->add('save', 'submit', ['label' => 'Save']);
$builder->setAction($this->urlGenerator->generate('page_create_element', [
'suiteId' => $options['suiteId'], 'pageId' => $options['pageId']
]))->setMethod('POST');
}
问题:有什么方法可以让上面的表单命令自动生成我的 ul / li 要求而不是选择,或者我是否必须手动呈现它并为此忽略 symfony 表单组件?
Thanks to some of the posters above, there was some information from Form Theming, but it wasn't exactly enough to go along with so I had to do a little bit of digging on github.
根据 documentation,Symfony 使用 twig 模板呈现表单的相关位及其包含的元素。这些只是树枝中的 {% block %}
s。所以第一步是找到在 symfony 代码库中呈现 select 按钮的位置。
表单主题
首先,您在自己的 twig 文件中创建自己的主题块,然后使用以下代码将此主题应用于您的表单:
{% form_theme my_form_name 'form/file_to_overridewith.html.twig %}
因此,如果我在上面的文件中覆盖了 {% block form_row %}
,那么当我调用 {{ form_row(form) }}
时,它将使用我的块而不是 Symfony 的默认块。
重要提示:您不必覆盖所有内容。只需覆盖您想要更改的内容,如果在您的主题中找不到任何内容,Symfony 将回退到它自己的块。
源代码
在 github 上,我找到了 Symfony 的 "choice widget" 的 source code。它有点复杂,但如果您按照它进行操作并进行一些实验,您就会明白它的走向。
在 choice_widget_collapsed
块中,我将 select 更改为 ul
,并将选项更改为 li
。这是我创建的主题文件,请注意上面描述的细微差别:
{# Symfony renders a 'choice' or 'entity' field as a select dropdown - this changes it to ul/li's for our own CSS #}
{%- block choice_widget_collapsed -%}
{%- if required and empty_value is none and not empty_value_in_choices and not multiple -%}
{% set required = false %}
{%- endif -%}
<ul {{ block('widget_attributes') }}{% if multiple %} multiple="multiple"{% endif %}>
{%- if preferred_choices|length > 0 -%}
{% set options = preferred_choices %}
{{- block('choice_widget_options') -}}
{%- if choices|length > 0 and separator is not none -%}
<li disabled="disabled">{{ separator }}</li>
{%- endif -%}
{%- endif -%}
{%- set options = choices -%}
{{- block('choice_widget_options') -}}
</ul>
{%- endblock choice_widget_collapsed -%}
{%- block choice_widget_options -%}
{% for group_label, choice in options %}
{%- if choice is iterable -%}
<optgroup label="{{ group_label|trans({}, translation_domain) }}">
{% set options = choice %}
{{- block('choice_widget_options') -}}
</optgroup>
{%- else -%}
<li value="{{ choice.value }}"{% if choice is selectedchoice(value) %} selected="selected"{% endif %}><a href="#">{{ choice.label|trans({}, translation_domain) }}</a></li>
{%- endif -%}
{% endfor %}
{%- endblock choice_widget_options -%}
渲染
现在我可以使用以下内容呈现我的表单:
{{ form_widget(form.locator, {'attr': {'class': 'dropdown-menu'}}) }}
这将我的主题用于选择下拉菜单,其中包含 ul
和 li
标签而不是 select
和 option
标签。一旦您知道在哪里寻找原始代码,就非常简单!呈现的 HTML:
<ul id="elementtype_locator" name="elementtype[locator]" required="required" class="dropdown-menu">
<li value="1"><a href="#">id</a></li>
<li value="2"><a href="#">name</a></li>
<li value="3"><a href="#">xpath</a></li>
</ul>
我还必须删除将 'Locator' 放在下拉列表顶部的行之一,因为有四个下拉选项(包括 empty_data 一个)而不是三个。