自定义表单字段模板与树枝

时间:2013-12-14 13:54:40

标签: symfony twig

我想在树枝中创建自定义模板以呈现表单字段。

示例:

{{ form_row(form.field) }}

这可以通过形成主题

来覆盖
{% block form_row %}
... custom code
{% endblock form_row %}

我想做的是:

{% block custom_row %}
... custom code
{% endblock custom_row %}

并像这样使用它:

{{ custom_row(form.field }}

但是,这会引发异常,即找不到方法custom_row

我的理解是,这可以通过Twig扩展来完成,但我不知道如何将块注册为函数。

更新

我真正想要的是什么:

我使用twitter bootstrap和一个覆盖所有表单主题的包。并且它在收音机周围呈现div,因此无法内联。所以我想做这样的事情:

复制他们的模板并摆脱div:

{% block inline_radio_row %}
    {% spaceless %}
        {% set col_size = col_size|default(bootstrap_get_col_size()) %}

        {% if attr.label_col is defined and attr.label_col is not empty %}
            {% set label_col = attr.label_col %}
        {% endif %}
        {% if attr.widget_col is defined and attr.widget_col is not empty %}
            {% set widget_col = attr.widget_col %}
        {% endif %}
        {% if attr.col_size is defined and attr.col_size is not empty %}
            {% set col_size = attr.col_size %}
        {% endif %}

        {% if label is not sameas(false) %}
            {% 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 %}
            {% if label is empty %}
                {% set label = name|humanize %}
            {% endif %}
            {% set label_attr = label_attr|merge({'class': (label_attr.class|default('') ~ ' radio-inline')|trim}) %}
            <label{% for attrname, attrvalue in label_attr %} {{ attrname }}="{{ attrvalue }}"{% endfor %}>
                {{ block('radio_widget') }}
                {{ label|trans({}, translation_domain) }}
            </label>
        {% else %}
            {{ block('radio_widget') }}
        {% endif %}
        {{ form_errors(form) }}
    {% endspaceless %}
{% endblock inline_radio_row %}

然后

{{ inline_radio_row(form.field) }}

我最终只是覆盖整个主题,并在问题的div周围添加了ifs,一个类(无线电内联)。但我仍然想知道是否有办法让这项工作成功。似乎它会让你如此努力地工作如此简单。

更新2

我找到了功能:

class FormExtension extends \Twig_Extension
{
    public function getFunctions()
    {
        return array(
            'inline_radio_row'  => new \Twig_Function_Node(
                'Symfony\Bridge\Twig\Node\SearchAndRenderBlockNode',
                array('is_safe' => array('html'))
            ),
        );
    }
}

这正是我想要的,但它表示已被弃用。有谁知道如何使用它的更新版本?

更新3

使用http://twig.sensiolabs.org/doc/tags/include.html

也可以实现类似的功能

2 个答案:

答案 0 :(得分:1)

您可以对表单行的每个部分使用twig函数:

例如:

<div class="form_row">
    {{ form_label(form.field) }} {# the name of the field #}
    {{ form_errors(form.field) }} {# the field #}
    {{ form_widget(form.field) }} {# the errors associated to the field #}
</div>

答案 1 :(得分:0)

您可以使用form theming

一步一步:

1。表单类型

检查班级名称

public function getName() {
  return 'hrQuestionResponse';
}

2。在模板中包含自定义主题

{% form_theme form 'InterlatedCamsBundle:Form:fields.html.twig' %}

3。找到块

可能很难。对于bootstrap bundle,你似乎已经发现它位于./vendor/braincrafted/bootstrap-bundle/Braincrafted/Bundle/BootstrapBundle/Resources/views/Form/bootstrap.html.twig,你找到了block radio_row。我一直在通过将输出放在源模板中并覆盖比我需要的更多的块来找到块。在2.7中有一个主题“rendering call graph”。

4。覆盖块

从主模板中复制块并调用它,将标准术语替换为步骤1中找到的FormType中的名称。

不要忘记也要更改结束名称。

e.g。

{% block hrQuestionResponse_widget %}
hrQuestionResponse_row
{% spaceless %}
    {% set class = '' %}
...
 {% endspaceless %}
{% endblock hrQuestionResponse_widget %}

在你的情况下因为你只能调用form_widget(),你需要覆盖_widget。您只能提取所需的内容,或者可以将块链覆盖到radio_row。