我正在使用Symfony2组件对遗留应用进行现代化改造。 我一直在尝试(并且大多数都是失败的)用树枝替换旧的php模板。
我挣扎的部分是:每个子模板都有自己的类,包含自己的逻辑(告诉你它是关于遗产的全部)。
所以,我创建了一个twig扩展,它调用模板类,然后包含子模板,传递类定义的变量(Here's the extension code)。
e.g:
{% template "NavBlockTemplate" %}
NavBlockTemplate
实例。
getTemplateName
以获取要包含的树枝模板文件getVariables
以获取模板所需的变量Twig_Node_Include
这里令人遗憾的是:每个模板都可以将变量传递给它的子模板类构造函数......
所以,我需要的是,但不确定它是否可能是这样的:
{% template "NavBlockTemplate" with { 'varName': value, 'var_id': otherVar.id }
Twig_Expression
个对象到php vars NavBlockTemplate
实例
getTemplateName
以获取要包含的树枝模板文件getVariables
以获取模板所需的变量Twig_Node_Include
那么,这可能吗?关于如何实现这一目标的任何提示?
答案 0 :(得分:1)
在编译模板期间无法访问变量值。他们还没有。
当你致电render($name, $context)
时,Twig有2个不同的阶段:
Twig_Environment::render()
:
public function render($name, array $context = array())
{
return $this->loadTemplate($name)->render($context);
}
您的自定义标记需要考虑到这一点。它需要创建一个特殊的节点类,它将被编译成您需要的逻辑。您可以查看现有Twig标签的实现方式
甚至您包含的类名也可以像编译时一样在编译时访问。 $expr->getAttribute('value')
仅在表达式是常量表达式时才起作用,并且您不在解析器中强制执行它。
另一方面,在这种情况下使用标签可能不是最好的解决方案(虽然它是最复杂的解决方案)。根据Twig的语义,函数会更好。这正是为什么Twig还引入了include()
函数,因为它更适合。这就是它的样子。
在模板中:
{{ include_legacy("NavBlockTemplate", { 'varName': value, 'var_id': otherVar.id }) }}
分机中的:
class LegacyIncludeExtension extends \TwigExtension
{
public function getFunctions()
{
return array(
new \Twig_SimpleFunction(
'include_legacy',
array($this, 'includeLegacy'),
array('is_safe' => array('all'), 'needs_environment' => true, 'needs_context' => true)
),
);
}
public function includeLegacy(\Twig_Environment $env, array $context, $name, array $variables = array())
{
$fqcn = // determine the class name
$instance = new fqcn();
$template = $instance->getTemplateName();
$variables = array_merge($instance->getVariables(), $variables);
return $env->resolveTemplate($template)->render(array_merge($context, $variables));
}
}
该方法的最后一行执行twig_include
的主要工作。如果需要支持隔离上下文,那么很容易(使模板的数组合并为条件)。对ignore_missing的支持更多,在这种情况下你最好直接调用twig_include
:
public function includeLegacy(\Twig_Environment $env, array $context, $name, array $variables = array(), $withContext = true, $ignoreMissing = false)
{
$fqcn = // determine the class name
$instance = new fqcn();
$template = $instance->getTemplateName();
$variables = array_merge($instance->getVariables(), $variables)
return twig_include($env, $context, $template, $variables, $withContext, $ignoreMissing);
}