php Symfony2/Twig - 迭代选择选项

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30846583/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 22:06:35  来源:igfitidea点击:

Symfony2/Twig - iterate over select options

phpsymfonytwig

提问by ex3v

Usual way of displaying selectfield is to call

显示select字段的通常方式是调用

{{ form_row(form.doctor_service_id, {'attr':{'class':'form-control'}}) }}

I would like to perform two things:

我想执行两件事:

  1. Check if this field is actually a select field
  2. Iterate over every option (value, name). I know how twigiterator works, I just don't know how to access selectoptions and cast them to it.
  1. 检查此字段是否实际上是一个选择字段
  2. 迭代每个选项(值,名称)。我知道twig迭代器是如何工作的,我只是不知道如何访问select选项并将它们转换为它。

回答by Jasmin Mistry

<select name="country"data-width="100%">
    {% for key,val in form.country.vars.choices %}
        <option value="{{ val.value }}" {{  form.country.vars.value == '' and key == 0 ? ' selected ' :(val.value == form.country.vars.value ? ' selected ' : '') }}>{{ val.label | trans }}</option>
    {% endfor %}
</select>

回答by redbirdo

  1. You can use a twig extension to add a twig 'instanceof' operator. If you are not familiar with creating twig extensions see How to Write a Custom Twig Extensionin the Symfony docs. There is a gist which gives an example of a Twig extension that implements an instanceof operator. Then to check if a field is a select field use:

      {% if value is instanceof('ChoiceType') %}
    
  2. This is not as straightforward as you might think because choice fields have so many options. With Symfony it is the form theme that determines how the various field types are rendered into html. The default form theme is in form_div_layout.html.twig. It takes about 50 lines of code to render a choice field taking account of all the options, covered by the blocks choice_widget, choice_widget_expanded, choice_widget_collapsed and choice_widget_options. You could pick out the bits you need based on the options you have set for your choice field and paste them into your twig template but then setting choice options in the form class wouldn't have any affect. The correct way to custom render your choice options (*assuming the select is not expanded) is to override the choice_widget_optionsblock from the form theme. Form Customizationis a topic in itself but the simplest approach is to override the block as a one-off within your twig template and then modify it to meet your needs e.g.

    {% extends '::base.html.twig' %}
    
    {% form_theme form _self %}
    
    {%- block choice_widget_options -%}
        {% for group_label, choice in options %}
            {%- if choice is iterable -%}
                <optgroup label="{{ choice_translation_domain is sameas(false) ? group_label : group_label|trans({}, choice_translation_domain) }}">
                    {% set options = choice %}
                    {{- block('choice_widget_options') -}}
                </optgroup>
            {%- else -%}
                {% set attr = choice.attr %}
                <option value="{{ choice.value }}" {{ block('attributes') }}{% if choice is selectedchoice(value) %} selected="selected"{% endif %}>{{ choice_translation_domain is sameas(false) ? choice.label : choice.label|trans({}, choice_translation_domain) }}</option>
            {%- endif -%}
        {% endfor %}
    {%- endblock choice_widget_options -%}
    
    {% block content %}
        {# ... render the form #}
    
        {{ form_row(form.doctor_service_id, {'attr':{'class':'form-control'}}) }}
    {% endblock %}
    
  1. 您可以使用树枝扩展来添加树枝“instanceof”运算符。如果您不熟悉创建树枝扩展,请参阅Symfony 文档中的如何编写自定义树枝扩展。有一个要点给出了一个实现 instanceof 运算符Twig 扩展的例子。然后检查一个字段是否是一个选择字段使用:

      {% if value is instanceof('ChoiceType') %}
    
  2. 这并不像您想象的那么简单,因为选择字段有很多选项。在 Symfony 中,表单主题决定了如何将各种字段类型呈现为 html。默认表单主题在form_div_layout.html.twig 中。考虑到块所涵盖的所有选项,大约需要 50 行代码来呈现一个选择字段choice_widget, choice_widget_expanded, choice_widget_collapsed and choice_widget_options。您可以根据您为选择字段设置的选项挑选出您需要的位并将它们粘贴到您的树枝模板中,但是在表单类中设置选择选项不会有任何影响。自定义呈现您的选择选项(*假设选择未展开)的正确方法是覆盖choice_widget_options表单主题中的块。表单定制本身就是一个主题,但最简单的方法是在树枝模板中一次性覆盖该块,然后对其进行修改以满足您的需求,例如

    {% extends '::base.html.twig' %}
    
    {% form_theme form _self %}
    
    {%- block choice_widget_options -%}
        {% for group_label, choice in options %}
            {%- if choice is iterable -%}
                <optgroup label="{{ choice_translation_domain is sameas(false) ? group_label : group_label|trans({}, choice_translation_domain) }}">
                    {% set options = choice %}
                    {{- block('choice_widget_options') -}}
                </optgroup>
            {%- else -%}
                {% set attr = choice.attr %}
                <option value="{{ choice.value }}" {{ block('attributes') }}{% if choice is selectedchoice(value) %} selected="selected"{% endif %}>{{ choice_translation_domain is sameas(false) ? choice.label : choice.label|trans({}, choice_translation_domain) }}</option>
            {%- endif -%}
        {% endfor %}
    {%- endblock choice_widget_options -%}
    
    {% block content %}
        {# ... render the form #}
    
        {{ form_row(form.doctor_service_id, {'attr':{'class':'form-control'}}) }}
    {% endblock %}
    

If you don't need to customise the rendering of your choice field but just want to get the data to do something else with it then the best thing to do is pass the data (that is mapped to the choice field) to the twig template along with the form and use it directly. If that is not an option it is possible to iterate over the choices as in the form theme although you may need to take account of preferred choices. The simplest case would be e.g.

如果您不需要自定义选择字段的渲染,而只想让数据用它做其他事情,那么最好的做法是将数据(映射到选择字段)传递给树枝模板连同表格并直接使用。如果这不是一个选项,则可以像在表单主题中一样迭代选项,尽管您可能需要考虑首选选项。最简单的情况是例如

{% for choice in form.doctor_service_id.vars.choices %}
    {{ choice.label }}
    {{ choice.value }}
{% endfor %}