2016-04-28 52 views
8

我有container.twig包含component.twig並傳遞一個名爲'mock'的對象。包含一個樹枝文件並從一個單獨的文件傳遞變量?

在container.twig:

{% set mock = { 
    title : "This is my title" 
} 
%} 

{% include 'component.twig' with mock %} 

這是工作正常,但我想模擬數據移動到它自己的文件。這個心不是工作:

Container.twig

{% include 'component.twig' with 'mock.twig' %} 

在mock.twig

{% set mock = { 
    title : "This is my title" 
} 
%} 

進出口使用一飲而盡,樹枝,但它的工作原理是在大多數方面標準的樹枝。 https://github.com/zimmen/gulp-twig

+0

是否有一個或兩個文件在第二個代碼塊? –

+1

@ A.L他們是單獨的文件,我更新了我的問題。 – Evans

+0

你能否說出你爲什麼要這樣做?看一下[include](http://twig.sensiolabs.org/doc/tags/include.html)文檔中不需要模板名稱。也許你可以用自定義的小枝功能解決它。 – DarkBee

回答

2

問題

嫩枝上下文從不存儲在模板對象,所以這將是很難找到一個乾淨的方式來實現這一目標。例如,下面的嫩枝代碼:

{% set test = 'Hello, world' %} 

將編譯到:

<?php 

class __TwigTemplate_20df0122e7c88760565e671dea7b7d68c33516f833acc39288f926e234b08380 extends Twig_Template 
{ 
    /* ... */ 

    protected function doDisplay(array $context, array $blocks = array()) 
    { 
     // line 1 
     $context["test"] = "Hello, world"; 
    } 

    /* ... */ 
} 

正如你所看到的,繼承的上下文不傳遞到由參考doDisplay方法,並且永遠不會存儲在對象本身(如$this->context = $context)。此設計允許模板可重複使用,並且內存友好。

解決方法1:使用全局變量

我不知道你是知道的嫩枝Global Variables。你可以用它們做一堆黑客。

最簡單的用法是將所有的全局變量加載到你的樹枝環境中。

$loader = new Twig_Loader_Filesystem(__DIR__.'/view'); 
$env = new Twig_Environment($loader); 
$env->addGlobal('foo', 'bar'); 
$env->addGlobal('Hello', 'world!'); 

然後,你可以把你的整個應用程序中使用{{ foo }}{{ Hello }}

但也有2個問題在這裏:

  • 當你試圖從樹枝文件加載變量,我假設你有很多的變量,這取決於您的功能初始化,並且不希望加載所有的時間。

  • 您正在從PHP腳本加載變量而不是來自Twig,並且您的問題想從一個樹枝文件導入變量。

解決方法2:用一根樹枝延伸

您還可以創建一個存儲擴展,它提供了一個save功能某處堅持一些模板的情況下,和一個restore功能合併在一個又一個這樣存儲的上下文。

proof_of_concept.php

<?php 

require __DIR__.'/vendor/autoload.php'; 

class StorageTwigExtension extends Twig_Extension 
{ 
    protected $storage = []; 

    public function getFunctions() { 
     return [ 
      new Twig_SimpleFunction('save', [$this, 'save'], ['needs_context' => true]), 
      new Twig_SimpleFunction('restore', [$this, 'restore'], ['needs_context' => true]), 
     ]; 
    } 

    public function save($context, $name) { 
     $this->storage = array_merge($this->storage, $context); 
    } 

    public function restore(&$context, $name) { 
     $context = array_merge($context, $this->storage); 
    } 

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

/* usage example */ 

$loader = new Twig_Loader_Filesystem(__DIR__.'/view'); 
$env = new Twig_Environment($loader); 

$env->addExtension(new StorageTwigExtension()); 

echo $env->render('test.twig'), PHP_EOL; 

樹枝/ variables.twig

{% set foo = 'bar' %} 
{% set Hello = 'world!' %} 
{{ save('test') }} 

樹枝/ test.twig

{% include 'variables.twig' %} 
{{ restore('test') }} 
{{ foo }} 

注意:如果你只想要導入變量,而無需實際渲染裏面有什麼樹枝/ variables.twig,你也可以使用:

{% set tmp = include('variables.twig') %} 
{{ restore('test') }} 
{{ foo }} 

最後說明

我不習慣JavaScript的樹枝端口,但它看起來像你仍然可以擴展它,這是你的去:)

3

由於Twig的範圍規則(我假設它是由gulp版本複製的),因此無法在不創建輔助函數的情況下從子模板向上傳遞變量。你可以做的最接近的事情是使用繼承來複制它。

因此,您mock.twig文件將成爲

{% set mock = { 
     title : "This is my title" 
    } 
%} 
{% block content %}{% endblock %} 

你container.twig將隨即成爲

{% extends 'mock.twig' %} 
{% block content %} 
    {% include 'component.twig' with mock %} 
{% endblock %} 

這實現你從最模板分離模擬內容的目標部分和,使用動態擴展,你可以做類似

{% extends usemock == 'true' 
    ? 'contentdumper.twig' 
    : 'mock.twig' %} 

帶con tentdumper.twig文件就像這樣

{% block content %}{% endblock %} 

存根,然後設置usemock變量來確定,如果你要使用的模擬數據,或者沒有。

希望這會有所幫助,儘管它並不能真正解決您遇到的確切問題。

相關問題