Symfony Twig为集合定制Individual字段

时间:2013-06-18 14:12:40

标签: symfony twig

在文档中,根据窗口小部件的名称/ ID,Symfony中有customize a Individual field的方式。

{% form_theme form _self %}

{% block _product_name_widget %}
    <div class="text_widget">
        {{ block('field_widget') }}
    </div>
{% endblock %}

{{ form_widget(form.name) }}

这里,_product_name_widget片段定义了用于id为product_name的字段的模板(名称为product [name])。

这适用于普通的窗口小部件,但如果窗口小部件位于集合中则不适用。因为额外的列。像这样:

name="productbundle_product_type[foobar][1][value]" id="productbundle_product_type_foobar_1_value"

在集合中进行Twig自定义工作的方法是什么?

我认为这样的事情,但这不起作用:

{% for db in edit_form.list %}
    {% block _productbundle_product_type_foobar_{{ db.name }}_widget %}
        <div class="text_widget">
            {{ block('field_widget') }}
        </div>
    {% endblock %}
{% endfor %}

即使以下情况也不起作用:

{% _productbundle_product_type_foobar_1_value_widget %}

使它运作的方法是什么?

3 个答案:

答案 0 :(得分:3)

我在几个晚上前正在研究一个项目并且遇到了这个问题 - 我发现的解决方案是一对看起来像这样的块(剥离了项目特定的代码):

{# Collection markup #}
{% block my_collection_widget %}
    {# Customise collection row prototype for allow_add #}
    {% if prototype is defined %}
        {% set data_prototype = block('my_collection_item_widget')  %}
        <div id="my_prototype" data-prototype="{{ data_prototype }}" style="display: none"></div>
    {% endif %}

    {% for prototype in form %}
        {{ block('my_collection_item_widget') }}
    {% endfor %}
{% endblock my_collection_widget %}

{# Collection row markup #}
{% block my_collection_item_widget %}
    {# Collection contains simple, single type #}
    {{ form_errors(prototype) }}
    {{ form_label(prototype) }}
    {{ form_widget(prototype) }}

    {# OR #}

    {# Collection contains a compound type, render child types independantly #}
    {{ form_errors(prototype.inner_widget) }}
    {{ form_label(prototype.inner_widget) }}
    {{ form_widget(prototype.inner_widget) }}
{% endblock my_collection_item_widget %}

答案 1 :(得分:0)

我知道这是个老问题,但是也许人们仍然对此事发生着。 fragment naming for collections对此进行了说明。

在这种情况下,您使用_entry_代替收集元素编号。使用链接中的说明进行片段命名,但这可能会有所不同。有时“类型”是片段名称的一部分,有时首字母是大写字母,有时是小写字母,等等。我将使用浏览器开发人员工具来查找实际名称以确保。您还可以通过将getBlockPrefix函数添加到表单类中来定制使用的名称。

因此,在上述情况下,自定义块可能类似于:

{% block _ProductBundle_product_entry_widget %}
   <div> {{ form_row(form.field)}} </div>
{% endblock %}

“字段”是集合元素中字段的名称。

答案 2 :(得分:0)

这里有几点:

1.文档错误

带有 CamelCase 实体的 docs seem to be a bit off。至于 5.3 应该是:_taskManager_taskLists_entry_widget(而不是 _task_manager_task_lists_entry_widget

您可以通过在模板中转储表单或表单字段来确认命名:{{ dump(form) }}{{ dump(form.yourField) }},然后在 unique_block_prefix 部分中查找 vars

2.不要使用块覆盖,宏更容易

它使事情绝对比必要的复杂。只需定义一个宏:

{% import _self as formMacros %}
{% macro formatCollection(form) %}
    <div class="form-group row">
        <div>
            {{ form_widget(form.field1) }}
            {{ form_widget(form.field2) }}
            {{ form_widget(form.field3) }}
        </div>
    </div>
{% endmacro %}

然后简单地在每个集合上运行它:

{% for item in form.collectionItems %}
    {{ formMacros.formatCollection(item) }}
{% endfor %}

3.原型

在呈现集合字段之前获取原型。您可以将其存储在变量中。

{% set prototype = form.collection.vars.prototype %}

然后只要你喜欢使用我们的宏就可以渲染它:

<div data-js="collection" data-prototype="{{ formMacros.formatCollection(prototype)|e('html_attr') }}">