如何分析枝条模板而不渲染它们?

时间:2015-09-16 16:53:06

标签: php parsing templates twig

对于我们正在开发的自定义CMS,我们希望使用twig模板(因为这是我们的前端构建的)。模板可以使用"默认" twig提供的一组功能(比如包括,块,标签,功能,你可以命名),但我们也想提供某些"小部件"到页面。

例如,模板可能如下所示:

<h1>{{ 'our_products'|translate }}</h1>

{{ widget_search(widget_parameters) }}

widget_开头的所有函数调用都是我们特殊的CMS小部件。

在后端,我们希望编辑人员填写我们的小部件所需的参数。因此,对于包含widget_search的模板,应该向他们显示输入字段,他们可以输入搜索字词,但是他们不应该更改其他内容。对于每种页面类型,我们都会创建一个由我们的前端开发人员手工制作的模板。

我现在的问题是:我们如何分析树枝模板并提取所有函数调用的列表,以便我们可以构建后端GUI(不为后端呈现模板)?

我调查Twig_Parser,但我不确定如何利用它?特别是,如果它包含其他文件会发生什么?这会被解析器解决吗?

(因为后端GUI是面向公众的网站的单独应用程序(但他们都知道模板文件),我们不能简单地渲染模板,因为前端可能已经注册了后端的Twig函数无法执行。)

1 个答案:

答案 0 :(得分:5)

在渲染之前,Twig代码是:

  • loaded(返回包含树枝模板的字符串)
  • tokenized(返回令牌的TokenStream,模板中包含的所有Twig元素)
  • 解析(返回一个Node_Module,一个包含模板对象表示的树)
  • 编译(返回包含与twig模板对应的php代码的字符串)

对你有用的对象是Node_Module:你可以递归地遍历它以便很容易地找到所有函数(或其他任何东西)。

示例(使用原生Twig功能,因为我没有你的功能):

<?php

require("vendor/autoload.php");

$env = new \Twig_Environment(new \Twig_Loader_Array(array()));
$template = "

<h1>{{ 'our_products'|upper }}</h1>

{{ max([1,random(),random()]) }}

";

$tree = $env->parse($env->tokenize($template));

$functions = array();
listFunctionCalls($tree, $functions);

function listFunctionCalls($node, array &$list) {
  if ($node instanceof \Twig_Node_Expression_Function) {
    $name = $node->getAttribute('name');
    if (!in_array($name, $list)) {
       $list[] = $name;
    }
  }
  if ($node) {
    foreach ($node as $child) {
      listFunctionCalls($child, $list);
    }
  }
}

var_dump($functions);

给出以下结果:

$ php test.php 
array(2) {
  [0]=>
  string(3) "max"
  [1]=>
  string(6) "random"
}

你可以使用树做任何事情,享受!