7

关于 symfony2 表单组件及其模板的问题:

我有一堆复选框可以设置样式(一个表单行中大约有 10 个)。通常我以<label>这种方式使用标签:<label><input/> some text</label>但我找不到在表单模板(form_div_layout.html.twig)中更改它的方法。我什至找不到将任何标签包装在输入小部件及其标签周围的方法,而且我总是以这样的标记结束:<input/> <some_tag><label>some text</label></some_tag>或者<some_tag><input/></some_tag> <label>some text</label>至少可以说这不是很有用......

谷歌了很多,但找不到答案。

4

4 回答 4

5

Whistlegreg 是正确的,您需要覆盖树枝表单模板。但是,您不需要删除该{% block generic_label %}块。如果您需要有关如何覆盖模板的帮助,请参阅他的回答。

为了用标签包装复选框输入标签,第一步是覆盖{% block choice_widget %}块并从打印出单独标签{{ form_label(child) }}的部分中删除该行。{% if expanded %}

{% block choice_widget %}
{% spaceless %}
    {% if expanded %}
        <div {{ block('widget_container_attributes') }}>
        {% for child in form %}
            {{ form_widget(child) }}
        {#  {{ form_label(child) }} <--------------------- remove this line #}  
        {% endfor %}
        </div>
    {% else %}
    <select {{ block('widget_attributes') }}{% if multiple %} multiple="multiple"{% endif %}>
        {% if empty_value is not none %}
            <option value="">{{ empty_value|trans }}</option>
        {% endif %}
        {% if preferred_choices|length > 0 %}
            {% set options = preferred_choices %}
            {{ block('widget_choice_options') }}
            {% if choices|length > 0 and separator is not none %}
                <option disabled="disabled">{{ separator }}</option>
            {% endif %}
        {% endif %}
        {% set options = choices %}
        {{ block('widget_choice_options') }}
    </select>
    {% endif %}
{% endspaceless %}
{% endblock choice_widget %}

现在您只需要处理打印{% block checkbox_widget %}块中的标签。

{% block checkbox_widget %}
{% spaceless %}
    <label  for="{{ id }}"><input type="checkbox" {{ block('widget_attributes') }}{% if value is defined %} value="{{ value }}"{% endif %}{% if checked %} checked="checked"{% endif %} />{{ label|trans }}</label>
{% endspaceless %}
{% endblock checkbox_widget %}

您将需要这样做,{% block radio_widget %}因为它现在不会有标签。

{% block radio_widget %}
{% spaceless %}
    <label  for="{{ id }}"><input type="radio" {{ block('widget_attributes') }}{% if value is defined %} value="{{ value }}"{% endif %}{% if checked %} checked="checked"{% endif %} />{{ label|trans }}</label>
{% endspaceless %}
{% endblock radio_widget %}
于 2012-08-19T21:58:29.917 回答
4

我认为这就是你要找的东西: http ://symfony.com/doc/current/book/templating.html#overriding-bundle-templates

您可以通过在 app/resources 文件夹中创建另一个同名文件来覆盖任何默认的树枝模板。

在您的情况下,您想覆盖 form_div_layout.html.twig 模板,将其从捆绑包复制到 app/Resources/TwigBundle/views/Form/form_div_layout.html.twig,自定义,symfony 将使用它而不是默认值。

编辑:一旦您覆盖了模板,您可以修改{% block checkbox_widget %}以使用 twig vars 用标签标签包装输入

<label{% for attrname,attrvalue in attr %} {{attrname}}="{{attrvalue}}"{% endfor %}>
  {{label|trans }} 
  <input type="checkbox" {{ block('widget_attributes') }}{% if value is defined %} value="{{ value }}"{% endif %}{% if checked %} checked="checked"{% endif %} /> 
</label> 

您还需要删除“generic_label”定义,这意味着每个其他块都需要修改。

于 2012-05-30T17:31:30.277 回答
1

可以为特定表单小部件类型的行定义块,例如{% block checkbox_row %}. 我在这里发现了这个:http: //forum.symfony-project.org/viewtopic.php?f=23 &t=57986#p153546

然后将标签包裹在复选框的小部件周围所需的所有内容如下:

{% block checkbox_row %}
{% spaceless %}
    <div>
        {% if not compound %}
            {% set label_attr = label_attr|merge({'for': id}) %}
        {% endif %}
        {% if required %}
            {% set label_attr = label_attr|merge({'class': (label_attr.class|default('') ~ ' required')|trim}) %}
        {% endif %}
        <label{% for attrname, attrvalue in label_attr %} {{ attrname }}="{{ attrvalue }}"{% endfor %}>{{ label|trans({}, translation_domain) }}
        {{ form_widget(form) }}
        {% if label is empty %}
            {% set label = name|humanize %}
        {% endif %}
        </label>
        {{ form_errors(form) }}
    </div>
{% endspaceless %}
{% endblock checkbox_row %}

标签代码已从 复制并粘贴{% block form_label %}。当我使用 Zurb 的 Foundation 框架时,我已将表单错误放在小部件下方。

单选按钮的代码更复杂,因为{% block radio_row %}它似乎不存在,所以你必须接受 Whistlegreg 的建议并编辑该{% block choice_widget %}块,在 Symfony 2.1 中这实际上是现在的{% block choice_widget_expanded %}. 这是我的代码:

{% block choice_widget_expanded %}
{% spaceless %}
    <div {{ block('widget_container_attributes') }}>
    {% for child in form %}
        {% set child_label = child.get('label') %}
        {% if child_label is not sameas(false) %}
            {% set child_id = child.get('id') %}
            {% set child_compound = child.get('compound') %}
            {% set child_required = child.get('required') %}
            {% set child_label_attr = child.get('label_attr') %}
            {% if not child_compound %}
                {% set child_label_attr = child_label_attr|merge({'for': child_id}) %}
            {% endif %}
            {% if child_required %}
                {% set child_label_attr = child_label_attr|merge({'class': (child_label_attr.class|default('') ~ ' required')|trim}) %}
            {% endif %}
            <label{% for attrname, attrvalue in child_label_attr %} {{ attrname }}="{{ attrvalue }}"{% endfor %}>
        {% endif %}
        {{ form_widget(child) }}
        {% if child_label is not sameas(false) %}
            {% if child_label is empty %}
                {% set child_label = name|humanize %}
            {% endif %}
            {{ child_label|trans({}, translation_domain) }}
            </label>
        {% endif %}
    {% endfor %}
    </div>
{% endspaceless %}
{% endblock choice_widget_expanded %}

在 Symfony 2.1.9 DEV 中测试和工作。

于 2013-03-03T16:58:05.913 回答
0

我认为您可以通过更改 form_row 块来做到这一点。

尝试这样的事情:

{% block form_row %}
{% spaceless %}
    <label>
        {{ form_widget(form) }}
    </label>
{% endspaceless %}
{% endblock form_row %}

但请注意,这绝对不是一个非常灵活的解决方案......
您可能应该只将它用于特定类型,而不是全部使用。
无论如何,您必须使用form_row它才能正常工作。

于 2012-05-30T18:48:15.607 回答