扩展Twig的AppVariable

时间:2015-06-19 05:40:45

标签: php symfony twig

我继承了一个使用Symfony 2的网站。

该网站运行正常,直到我运行composer升级软件包。它将Symfony 2.6升级到2.7.1,将Twig 1.18升级到1.18.2。

我现在收到以下错误:

  

对象“Symfony \ Bridge \ Twig \ AppVariable”的方法“site”在第21行的@ Page / Page / homepage.html.twig中不存在

有问题的树枝文件有这样的调用:

{{ app.site.name }}

现在显然site不是AppVariable类型的成员。我无法弄清楚原始开发人员是如何通过新成员扩展Twig的app全局的。我真的不知道在哪里看。我对Symfony并不过分称职。

2 个答案:

答案 0 :(得分:9)

旧开发人员可能做的是覆盖app变量。在Symfony @ 2.7之前,该类被称为GlobalVariables并且位于以下命名空间 - Symfony\Bundle\FrameworkBundle\Templating。从@ 2.7开始,它被称为AppVariable,它存在于此命名空间中 - Symfony\Bridge\Twig。在幕后做了什么?

使用Twig的方法addGlobal将包含全局变量的类简单地添加为twig全局变量,并且对于app的值,它们将整个类注入已定义的服务。 GlobalVariablesAppVariables接受服务容器作为参数,并默认定义5个可在模板中使用的方法。我将向您展示一种扩展该类的简单方法,以便您可以使用它进行调查。

创建我们将定义为服务的简单类:

<?php

namespace AppBundle\Service;

use Symfony\Bundle\FrameworkBundle\Templating\GlobalVariables,
    Symfony\Component\DependencyInjection\ContainerInterface;

class SuperGlobalsExtended extends GlobalVariables {

    /**
     * @var ContainerInterface
     **/
    protected $container = null;

    public function __construct(ContainerInterface $container) {
        $this->container = $container;

        parent::__construct($container);
    }

}

然后注册:

services:
    app.super_globals_extended:
        class: AppBundle\Service\SuperGlobalsExtended
        arguments:
            - @service_container

最后但并非最不重要的是,覆盖twig的app变量:

twig:
    debug:            "%kernel.debug%"
    strict_variables: "%kernel.debug%"
    globals:
        app: @app.super_globals_extended

现在,您可以在扩展类中定义自己的方法,也可以访问之前已经存在的方法。

对于symfony @ 2.7是相同的,只是类名不同。在这里,我扩展了GlobalVariables,但对于@ 2.7,您必须扩展AppVariable

位于TwigBundle Resources文件夹中的@ 2.7服务的定义。

<service id="twig" class="%twig.class%">
        <argument type="service" id="twig.loader" />
        <argument /> <!-- Twig options -->
        <call method="addGlobal">
            <argument>app</argument>
            <argument type="service" id="twig.app_variable" />
        </call>
        <configurator service="twig.configurator.environment" method="configure" />
    </service>

希望这有帮助。

答案 1 :(得分:0)

请参考Artamiels answer作为起点。

与sf3一样,AppVariable类不再需要容器(并且没有parent::__construct),但是直接设置了有趣的变量。

所以,我确实在class MyAppExtension extends AppVariable中设置了services.yml这个设置:

extended_twig_app:
  class: AppBundle\Twig\MyAppExtension
  public: false
  calls:
    - [setEnvironment, ["%kernel.environment%"]]
    - [setDebug, ["%kernel.debug%"]]
    - [setTokenStorage, ['@security.token_storage']]
    - [setRequestStack, ['@request_stack']]

这基本上是在Twig Bundle中转换了相应代码的xml-&gt; yml: https://github.com/symfony/twig-bundle/blob/master/Resources/config/twig.xml

    <service id="twig.app_variable" class="Symfony\Bridge\Twig\AppVariable" public="false">
        <call method="setEnvironment"><argument>%kernel.environment%</argument></call>
        <call method="setDebug"><argument>%kernel.debug%</argument></call>
        <call method="setTokenStorage"><argument type="service" id="security.token_storage" on-invalid="ignore" /></call>
        <call method="setRequestStack"><argument type="service" id="request_stack" on-invalid="ignore" /></call>
    </service>