[英]Extending Twig's AppVariable
I've inherited a website that uses Symfony 2. 我继承了一个使用Symfony 2的网站。
The site was working fine until I ran composer to upgrade packages. 该网站运行正常,直到我运行composer升级包。 It upgraded Symfony 2.6 to 2.7.1 and Twig 1.18 to 1.18.2.
它将Symfony 2.6升级到2.7.1,将Twig 1.18升级到1.18.2。
I now get the following error: 我现在收到以下错误:
Method "site" for object "Symfony\\Bridge\\Twig\\AppVariable" does not exist in @Page/Page/homepage.html.twig at line 21
对象“Symfony \\ Bridge \\ Twig \\ AppVariable”的方法“site”在第21行的@ Page / Page / homepage.html.twig中不存在
The twig file in question has calls like this: 有问题的twig文件有这样的调用:
{{ app.site.name }}
Now obviously site
is not a member of the AppVariable
type. 现在很明显,
site
不是AppVariable
类型的成员。 I'm having trouble figuring out how the original developers managed to extend Twig's app
global with a new member. 我无法弄清楚原始开发人员是如何通过新成员扩展Twig
app
全局的。 I don't really know where to look. 我真的不知道在哪里看。 I'm not overly competent with Symfony.
我对Symfony不太称职。
What probably was done by the old developers was overriding the app
variable. 旧开发人员可能做的是覆盖
app
变量。 Until Symfony @2.7 the class was called GlobalVariables
and lives in the following namespace - Symfony\\Bundle\\FrameworkBundle\\Templating
. 在Symfony @ 2.7之前,该类被称为
GlobalVariables
并且位于以下命名空间中 - Symfony\\Bundle\\FrameworkBundle\\Templating
。 As of @2.7 it's called AppVariable
and it lives in this namespace - Symfony\\Bridge\\Twig
. 从@ 2.7开始,它被称为
AppVariable
,它存在于这个命名空间中 - Symfony\\Bridge\\Twig
。 What is done behind the scenes? 在幕后做了什么?
That class containing the global variables is simply added as twig global variable using the method addGlobal
of Twig and for the value of app
they inject the whole class as a service that's already defined. 包含全局变量的类只是使用
addGlobal
方法添加为addGlobal
全局变量,对于app
的值,它们将整个类注入已定义的服务。 GlobalVariables
or AppVariables
accepts the service container as an argument and defines 5 methods by default that can be used in our templates. GlobalVariables
或AppVariables
接受服务容器作为参数,并默认定义5个方法,可以在我们的模板中使用。 I will show you a simple way of extending that class, so you can use it to investigate. 我将向您展示一种扩展该类的简单方法,以便您可以使用它来进行调查。
Create simple class that we will define as a service: 创建我们将定义为服务的简单类:
<?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);
}
}
Then register it: 然后注册:
services:
app.super_globals_extended:
class: AppBundle\Service\SuperGlobalsExtended
arguments:
- @service_container
And last but not least, override the app
variable of twig: 最后但并非最不重要的是,覆盖twig的
app
变量:
twig:
debug: "%kernel.debug%"
strict_variables: "%kernel.debug%"
globals:
app: @app.super_globals_extended
Now you can define your own methods in your extended class as well as accessing the previous methods that were already here. 现在,您可以在扩展类中定义自己的方法,也可以访问此处已有的先前方法。
For symfony @2.7 is the same, just the class name is different. 对于symfony @ 2.7是相同的,只是类名不同。 Here I extend the
GlobalVariables
, but for @2.7 you have to extend AppVariable
. 在这里我扩展了
GlobalVariables
,但对于@ 2.7,你必须扩展AppVariable
。
Definition of the service for @2.7 located in TwigBundle Resources folder. 位于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>
Hope this helps. 希望这可以帮助。
Refer to Artamiels answer as a starting point. 请参阅Artamiels答案作为起点。
Looks like with sf3, the AppVariable
class does no longer need the container (and does not have a parent::__construct
) but the interesting vars are being set directly. 看起来像sf3,
AppVariable
类不再需要容器(并且没有parent::__construct
),但是直接设置了有趣的变量。
So, I did set my class MyAppExtension extends AppVariable
with this setup in services.yml
: 所以,我也把我的
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']]
This is basically xml->yml converted of the coresponding code in the Twig Bundle: https://github.com/symfony/twig-bundle/blob/master/Resources/config/twig.xml 这基本上是在Twig Bundle中对相应代码进行xml-> 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>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.