0

是否有任何方法可以从 Twig 模板中发现所需的变量?例如,如果我有:

Hello {{ user }}! You're {{ age }} years old, well done big man!

我将能够加载这个模板,然后收集每个必需的变量,最终让我有类似的东西:

Array ( [0] => user [1] => age )

这样做的最终目标是能够定义一个视图,然后让系统根据模板文件中的所需变量创建一个表单。

4

4 回答 4

2

工作解决方案

感谢 morg 指出我tokenize能够使用以下内容获得我想要的东西(我将它放在我的控制器中进行测试):

$lexer = new \Twig_Lexer(new \Twig_Environment());
$stream = $lexer->tokenize(new \Twig_Source('{{test|raw}}{{test2|raw|asd}}{{another}}{{help_me}}', null));
$variables = array();
while (!$stream->isEOF()) {
    $token = $stream->next();
    if($token->getType() === \Twig_Token::NAME_TYPE){
        $variables[] = $token->getValue();
        while (!$stream->isEOF() && $token->getType() !== \Twig_Token::VAR_END_TYPE) {
            $token = $stream->next();
        }
    }
}
$variables = array_unique($variables);

这将返回:

Array
(
    [0] => test
    [1] => test2
    [2] => another
    [3] => help_me
)

你会注意到我只得到变量而不是任何函数(这是通过设计),但如果你想同时得到变量和函数,你可以删除嵌套的 while 循环。

于 2013-01-14T10:29:59.683 回答
1

您可以为此使用 twig 标记器。

$stream = $twig->tokenize($source, $identifier);

标记器有一个toString()方法,您可以解析其结果字符串

VAR_START_TYPE()
NAME_TYPE(varname)
VAR_END_TYPE()

查看内容以获取更多详细信息。

于 2013-01-12T14:24:32.120 回答
0

您可以尝试使用preg_match_all('{{\s*(\w+)\s*}}', 'template {{string }} with {{ var}}', $matchesArray);. 其$matchArray结构如下:

Array(
     0 => array(0 => '{{string }}', 1 => 'string'),
     1 => array(0 => '{{ var}}', 1 => 'var')
)
于 2013-01-11T16:21:02.730 回答
0

从 PHP 代码中执行此操作的另一种方法并不优雅,但仍然比任何正则表达式更可靠:

$source = "My template string with {{ some }} parameters.";

$stream = $twig->tokenize(new \Twig_Source($source, "source"));

$matches = [];
preg_match_all(
    "/NAME_TYPE\((.*)\)/", $stream->__toString(), $matches
);

if (count($matches) > 1) {
    $params = array_unique($matches[1]);
} else {
    $params = [];
}

这通过使用 Twig 内部机制来标记模板字符串,然后使用正则表达式提取参数名称来工作。

编辑:我的答案的先前版本使用 parse 方法来创建节点树,但它似乎不再起作用,并且在上一步中匹配 NAME_TYPE 似乎更可靠,不确定我是否错过了那里的东西......< /p>

于 2018-06-12T00:38:59.643 回答