我有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"
}
%}
我正在使用gulp-twig但它在大多数方面都像标准树枝一样工作。 https://github.com/zimmen/gulp-twig
答案 0 :(得分: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' %}
使用contentdumper.twig文件,它只是一个像这样的存根
{% block content %}{% endblock %}
然后设置usemock变量以确定您是否将使用模拟数据。
希望这有帮助,即使它并没有真正解决你遇到的确切问题。
答案 1 :(得分:2)
Twig上下文永远不会存储在模板对象中,因此要找到一种干净的方法来实现这一目标非常困难。例如,以下Twig代码:
{% 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
)。这个deisgn允许模板可重用,并且对内存有用。
我不知道您是否了解Twig中的Global Variables。你可以用它们做一堆黑客攻击。
最简单的用法是在树枝环境中加载所有全局变量。
$loader = new Twig_Loader_Filesystem(__DIR__.'/view');
$env = new Twig_Environment($loader);
$env->addGlobal('foo', 'bar');
$env->addGlobal('Hello', 'world!');
然后,您可以在整个应用程序中使用{{ foo }}
和{{ Hello }}
。
但这里有两个问题:
当您尝试从twig文件加载变量时,我假设您有很多变量要初始化,具体取决于您的功能,并且不希望一直加载所有内容。
您是从PHP脚本加载变量而不是从Twig加载变量,而您的问题是要从twig文件中导入变量。
您还可以创建一个存储扩展,提供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 }}
注意:如果您只想导入变量而不实际渲染 twig / variables.twig 中的内容,您还可以使用:
{% set tmp = include('variables.twig') %}
{{ restore('test') }}
{{ foo }}
我不习惯JavaScript twig端口,但看起来你仍然可以扩展它,那就是你的去吧:)