Create custom Twig node and parser #DSL
If You want to create custom twig node then this tutorial is for You. I will show you step by step how to create custom twig syntax (DSL) called gimme
(we build it for our Superdesk Publisher project).
Read more about this publisher feature here: Building a Template System for Your PHP Application.
Lest start with simplecomposer.json
file:
{
"require": {
"twig/twig": "^2.4"
},
"autoload": {
"psr-4": {
"SWP\\": "src/SWP/"
}
}
}
and run php composer.phar install
command.
let’s create demo entry point index.php
<?php
// load composer autoloader
require_once __DIR__.'/vendor/autoload.php';// define Twig loader with our simple template
$loader = new Twig_Loader_Array([
'index' => '{% gimme article with {\'foo\': \'bar\'} %} {{ dump(article) }} {% endgimme %}',
]);// create Twig instance and pass there our loader (and enable debug extension).
$twig = new Twig_Environment($loader, ['debug' => true]);
$twig->addExtension(new \Twig_Extension_Debug());// register our custom extension
$twig->addExtension(new \SWP\Extension\GimmeExtension());
echo $twig->render('index');
First we need to create Twig Extension:
src/SWP/Extension/GimmeExtension.php
Extension allows to register custom things in twig. Read more about it in docs: https://twig.symfony.com/doc/2.x/advanced.html#creating-an-extension. Our extension is simple and register only TokenParser and simplified data loader (in real world you will inject here some repository or provider).
First let’s look at our custom node syntax:
{% gimme article with {'foo': 'bar'} %} {# loaded data will be visible under `article` variable. #} {{ dump(user) }} {% endgimme %}
Step by step:
- gimme — tell for twig that you want to start our node
- article — this can tell for your loader what kind of data you want to load (data will be also available under this variable inside block).
- with — (optional) this will tell for parser that we pass extra parameters for loader
{'foo': 'bar'}
— (optional) extra parameters passed to loader- endgimme — tell for twig that you want to close our node
Now we need to write that GimmeTokenParser
(responsible for parsing the template code) [Docs can be found here].
TokenParser creates Node instance. Node is responsible for converting the parsed code to PHP.
Full working example can be found in this repository: https://github.com/ahilles107/twig-node-parser-tutorial
Check out our final implementation (with gimmelist
— node for collections loading with support for pagination) here: https://github.com/SuperdeskWebPublisher/templates-system
Thanks for reading this post. You can follow me on twitter: https://twitter.com/ahilles107 and on linkedin: https://www.linkedin.com/in/pawelmikolajczuk/