<?php
use Twig\Compiler;
use Twig\Token;
use Twig\Extension\AbstractExtension;
use Twig\TokenParser\AbstractTokenParser;
use Twig\Node\Node;
use Twig\Loader\FilesystemLoader;
use Twig\Environment;
// creating Twig Tag as Extension
class MyTwigTags extends AbstractExtension
{
public function getName()
{
return 'MyTags';
}
public function getTokenParsers()
{
return [new ListTokenParser()];
}
}
// parser of the new tag
class ListTokenParser extends AbstractTokenParser
{
public function getTag()
{
return 'list';
}
public function parse(Token $token)
{
$this->parser->getStream()->expect(Token::BLOCK_END_TYPE);
$body = $this->parser->subparse(array($this, 'decideSpacelessEnd'), true);
$this->parser->getStream()->expect(Token::BLOCK_END_TYPE);
return new ListNode($body, $token->getLine(), $this->getTag());
}
public function decideSpacelessEnd(Token $token)
{
return $token->test('endlist');
}
}
// interpretation and execution of tag and its values
class ListNode extends Node
{
public function __construct($body, $line, $tag)
{
parent::__construct(array('body' => $body), array(), $line, $tag);
}
public function compile(Compiler $compiler)
{
$compiler
->addDebugInfo($this)
->write('ob_start();' . PHP_EOL)
->subcompile($this->getNode('body'))
->write('$list = explode(PHP_EOL, trim(ob_get_clean()));' . PHP_EOL)
->write('echo \'<ul>\';' . PHP_EOL)
->write('foreach ($list as $node) {' . PHP_EOL)
->write('echo \'<li>\' . $node . \'</li>\';' . PHP_EOL)
->write('}' . PHP_EOL)
->write('echo \'</ul>\';' . PHP_EOL);
}
}
$path = __DIR__ . '/templates/';
$file = 'list.html.twig';
echo '<b>- template content:</b>' . PHP_EOL;
echo file_get_contents($path . $file) . PHP_EOL;
$loader = new FilesystemLoader($path);
$twig = new Environment($loader);
$twig->addExtension(new MyTwigTags());
echo '<b>- rendered template:</b>' . PHP_EOL;
echo $twig->render($file);