不同子站点的 symfony2 树枝形式主题

symfony2 twig form theme for different subsites

我有一个具有多种样式的 symfony2 应用程序。所有 3 个都有自己的 html + css 用于渲染。 类似于 "frontsite"、"user dashboard" 和 "admin backend".

现在所有 3 个子站点使用的表单主题有所不同,因此所有子站点都有一个(略微)不同的主题。

因此我可以在 symfony 配置中设置主题,但是对于 3 个子站点中的 2 个,它是错误的。

我可以手动设置主题:

{% form_theme form 'MyUberCoolBundle:Form:theme.html.twig' %}

但我真的不想对每个表单都这样做。 我可以在基本模板中设置它,但是我的表单总是需要被调用 "form"。

有没有办法设置要在基本模板中使用的主题,以便将其用于所有表单?

要为您的应用程序设置全局主题,您可以在配置中设置它

twig:
    form_themes:

        # Default:
        - form_div_layout.html.twig

        # Bootstrap:
        - bootstrap_3_layout.html.twig
        - bootstrap_3_horizontal_layout.html.twig

        # Example:
        - MyBundle::form.html.twig

查看完整的 Twig 配置参考 here

在四处寻找答案后,我得出结论,仅在配置中无法做到这一点。

我们采用了以下解决方案

在config.yml我们配置了一个全局的twig变量:

twig:
    globals:
        frontend_form_theme:          'MyUberCoolBundle:Form:theme.html.twig'

然后我们在使用全局变量呈现之前在表单本身上设置正确的主题。 这甚至允许我们在需要时使用不同的东西。

{% form_theme form frontend_form_theme %}
{{ form_start(form) }}

我正在寻找类似的东西。一个主题用于 FrontOffice,另一个用于后台。

我明白了。我像 FrontOffice 一样在 config.yml 中使用正常配置:

twig:
globals:
    frontend_form_theme:          'form/fields.html.twig'

然后我在主 BackOffice 模板中使用 layout.html.twig:

{% if oForm is defined %} {% form_theme oForm 'bootstrap_3_layout.html.twig' %} {% endif %}

因此,bootstrap 为名称为 oForm 的所有表单定义。

这是可行的,而且效果很好。但是,它假定您与根表单的命名保持一致。

首先,按照标准文档中的描述设置默认表单主题。

# twig.yaml
twig:
    form_themes: ['form.html.twig'] # Default theme and front-end

覆盖管理布局模板中主表单的表单主题。

# admin/layout.html.twig

{% if form is defined %}
    {% form_theme form "admin/_form.html.twig" %}
{% endif %}

{% block content %}{% endblock %}
...

可选择通过在表单块中设置表单主题来覆盖最终模板中的管理表单主题。如果您在块外定义表单主题,它将不起作用。您的自定义表单主题也应该扩展管理表单主题。

# admin/user/edit.html.twig

{% extends "admin/layout.html.twig" %}

{% block content %}
    {% form_theme form "admin/user/_form.html.twig" %}
    {{ form(form) }}
{% endblock %}

所以当您的页面只有一种形式并且它总是被命名为常量时,这里的其他答案很有效,比如 form。但是,在我的场景中,我经常有多个具有不同名称的表单,因此这种方法不起作用。相反,我所做的是创建一个自定义的树枝函数,将所需的表单主题应用于传递给视图的 所有 表单:

在您的 WhateverTwigExtension.php 中:(有关编写树枝扩展的信息,请参阅 here

class WhateverTwigExtension extends AbstractExtension
{
    private $formRenderer;

    public function __construct(FormRendererInterface $formRenderer)
    {
        $this->formRenderer = $formRenderer;
    }

    public function getFunctions()
    {
        return [
            new TwigFunction('applyFormThemes', [$this, 'applyFormThemes']),
        ];
    }

    public function applyFormThemes(array $context, $themes)
    {
        foreach ($context as $variable) {
            if ($variable instanceof FormView) {
                $this->formRenderer->setTheme($variable, $themes);
            }
        }
    }
}

请注意,为了让 symfony 的自动装配能够将渲染器注入到此扩展中,您必须为其添加别名,因此请在您的 services.yml:

中添加类似的内容
services:
    Symfony\Component\Form\FormRendererInterface: '@twig.form.renderer'

最后,在您的子站点的基础分支中,只需添加:

{{ applyFormThemes(_context, 'my_form_theme.html.twig') }}

也适用于多个主题:

{{ applyFormThemes(_context, ['my_form_theme.html.twig', 'other_form_theme.html.twig']) }}

现在传递给该视图的所有表单都将应用您的主题!

您仍然可以使用普通的 form_theme 标签来覆盖特定的形式,只要它出现在 applyFormThemes

之后