php - 如何在不渲染 Twig 模板的情况下分析它们?

标签 php parsing templates twig

对于我们正在开发的自定义 CMS,我们希望使用 twig 模板(因为这是我们的前端构建的基础)。模板可能会使用 twig 提供的“默认”功能集(如包含、 block 、标签、函数等),但我们也想为页面提供某些“小部件”。

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

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

{{ widget_search(widget_parameters) }}

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

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

我现在的问题是:我们如何分析一个 twig 模板并提取所有函数调用的列表,以便我们可以构建后端 GUI(无需为后端渲染模板)?

我查看了 Twig_Parser 但我不确定如何利用它?特别是,如果它包含其他文件会怎样?解析器会解决这个问题吗?

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

最佳答案

在渲染之前,Twig 代码是:

  • 加载(返回包含 Twig 模板的字符串)
  • 标记化(返回标记的标记流,模板中包含的所有 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"
}

您可以使用这棵树做任何事情,尽情享受吧!

关于php - 如何在不渲染 Twig 模板的情况下分析它们?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32614432/

相关文章:

php - 如何使用 Twig 生成随机字符串?

php - MySQL 表达式无效?

php - PHP 检查 if 语句有多远?

java - 如何使用 Jsoup 抓取 Google SERP?

c++ - g++ : constructor or operator = not matching? 错误“没有匹配的调用函数”

c++ - 在 C++ 的可变参数模板中获取可变参数 size_t... 参数的总和

php - UPDATE sql 查询并在一个查询中获取更新的字段

parsing - 如何正确解析 VB Case 语句?

java - 如何在Java中解析JSON

c++ - 为什么调用模板成员函数会出错?