For a custom CMS we are working on, we want to use twig templates (because that's what our frontend is built on). The templates may use the "default" set of functionality provided by twig (like including, blocks, tags, functions, you name it), but we also want to provide certain "widgets" to the pages.
A template might for example look like this:
<h1>{{ 'our_products'|translate }}</h1>
{{ widget_search(widget_parameters) }}
All function calls starting with widget_
are our special CMS widgets.
On the backend, we want our editors to fill in the parameters our widgets need. So for a template including a widget_search
for example, they should be presented with an input field where they can enter the search term, but they should not be able to change anything else. For each page type, we would create a template, handcrafted by our frontend developers.
My question is now: How can we analyze a twig template and extract a list of all function calls so that we can build the backend GUI (without rendering the template for the backend)?
I looked into Twig_Parser
but I'm not sure how I could utilize that? Especially, what happens if it includes other files? Would that be resolved by the Parser?
(Because the Backend GUI is a separate application from the public facing website (but they both know the template files), we can't simply render the template, as the frontend might have Twig functions registered which the backend simply couldn't execute.)
Before being rendered, Twig code is:
The object that will be useful for you is the Node_Module
: you can traverse it recursively to find all functions (or anything else) very easily.
Example (with native Twig functions because I don't have yours):
<?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);
Gives the following result:
$ php test.php
array(2) {
[0]=>
string(3) "max"
[1]=>
string(6) "random"
}
You can do anything using the tree, enjoy!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With