2013-02-01 71 views
1

在Symfony2的項目中使用的樹枝,我已經創建了一個實現Twig_ExtensionInterface這樣我就可以把它作爲一個嫩枝過濾服務,像{{ stuff|my_filter }}在自定義的樹枝擴展

在這個服務,我需要用小樹枝環境在所以我可以使用例如樹枝模板,所以我注入它作爲一個可以在服務做到:

services: 
    meta.twig.my_extension: 
     class: Acme\GeneralBundle\Twig\MyExtension 
     tags: 
      - { name: twig.extension } 
     arguments: 
      twig: "@twig" 

所以本身的服務看起來像:

在services.yml
<?php 

namespace Acme\GeneralBundle\Twig; 

class MyExtension extends \Twig_Extension 
{ 

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

    public function getFilters() 
    { 
     return array(
      'my_filter' => new \Twig_Filter_Method($this, 'myFunction'), 
     ); 
    } 

    public function myFunction($text) 
    { 
     return $this->twig->render($someTemplate,$someArguments); 
    } 
} 

我能在那樣的控制器使用方法:

$myService = $this->container->get('Acme.twig.my_extension'); 
$text = $myService->myFunction($someValue); 

但是,當然,我得到一個CircularReference錯誤這樣做時:

Circular reference detected for service "Acme.twig.my_extension", 
path: "Acme.twig.my_extension -> twig". 

那麼,什麼是在自定義Twig過濾器中使用twig-> render()函數的最佳方法是什麼?

非常感謝!

+1

你使用什麼版本的symfony?在2.1我沒有看到問題和這樣的例子,因爲你的工作沒有問題。您可以嘗試注入容器而不是twig_env和延遲加載樹枝。 – l3l0

+1

我正在使用版本2.1.8-DEV,但這個例子不起作用。我明白,注入整個容器是不好的做法,這就是爲什麼我走這條路......沒有效果,因爲有效地,樹枝環境似乎是以某種方式「遞歸地注入」的。我在網上找不到任何文獻以獲得一個好的解決方案 – tchap

+0

您是否嘗試刪除擴展的構造函數和服務文件中的參數部分? DIC應該照顧你。 –

回答

3

Twig_ExtensionInterface定義了接受樹枝環境作爲參數的initRuntime()方法。此方法在初始化擴展時由枝條調用。

您已將Twig_Extension課程延伸,其中already provides an empty implementation of this method。你所要做的就是覆蓋它並存儲一個引用到樹枝環境以供將來使用。

<?php 

namespace Acme\GeneralBundle\Twig; 

class MyExtension extends \Twig_Extension 
{ 
    private $environment = null; 

    public function initRuntime(\Twig_Environment $environment) 
    { 
     $this->environment = $environment; 
    } 

    public function getFilters() 
    { 
     return array(
      'my_filter' => new \Twig_Filter_Method($this, 'myFunction'), 
     ); 
    } 

    public function myFunction($text) 
    { 
     return $this->environment->render($someTemplate,$someArguments); 
    } 
} 

文檔:Creating an extension

+0

是的,這在我確實在樹枝模板中使用該服務時有效。但是,我怎麼把它稱爲服務,如下所示:$ myService = $ this-> container-> get('Acme.twig.my_extension'); $ text = $ myService-> myFunction($ someValue); ...我需要以某種方式通過樹枝環境 – tchap

+0

Twig環境在loadTemplate()中自動調用方法。我想你可以強制通過調用$ twig-> initRuntime()來初始化所有擴展。 –