How to create a twig custom tag that executes a callback?

前端 未结 2 1556
青春惊慌失措
青春惊慌失措 2020-11-30 01:31

I\'m trying to create a custom Twig tag such as this:

{% mytag \'foo\',\'bar\' %}
   Hello world!!
{% endmytag %}

This tag should print the

2条回答
  •  野性不改
    2020-11-30 02:11

    After looking at documentation.. Not sure that it follows all the standards, but it works..

    require 'Twig/Autoloader.php';
    Twig_AutoLoader::register();
    
    class MyTag_TokenParser extends Twig_TokenParser
    {
        public function parse(Twig_Token $token)
        {
            $parser = $this->parser;
            $stream = $parser->getStream();
    
            if (!$stream->test(Twig_Token::BLOCK_END_TYPE))   
               $values = $this->parser->getExpressionParser()
                              ->parseMultitargetExpression();
    
            $stream->expect(Twig_Token::BLOCK_END_TYPE);
    
            $body = $this->parser->subparse(array($this, 'decideMyTagEnd'), true);
    
            $stream->expect(Twig_Token::BLOCK_END_TYPE);
    
            return new MyTag_Node($body, $values, $token->getLine(), $this->getTag());
        }
    
        public function decideMyTagEnd(Twig_Token $token)
        {
            return $token->test('endmytag');
        }
    
        public function getTag()
        {
            return 'mytag';
        }
    }
    
    class MyTag_Node extends Twig_Node
    {
        public function __construct(Twig_NodeInterface $body, $values,
                                    $line, $tag = null)
        {
            if ($values)
               parent::__construct(array('body' => $body, 'values' => $values),
                                   array(), $line, $tag);
            else
               parent::__construct(array('body' => $body), array(), $line, $tag);        
        }
    
        public function compile(Twig_Compiler $compiler)
        {
            $compiler
                ->addDebugInfo($this)
                ->write("ob_start();\n")
                ->subcompile($this->getNode('body'))            
                ->write("my_func(ob_get_clean()");
    
            if ($this->hasNode('values'))
            foreach ($this->getNode('values') as $node) {
                $compiler->raw(", ")
                         ->subcompile($node);
            };
    
            $compiler->raw(");\n"); 
        }
    }
    
    function my_func()
    {
        $args = func_get_args();
        print_r($args);
    }
    
    $loader = new Twig_Loader_String();
    $twig = new Twig_Environment($loader);
    $twig->addTokenParser(new MyTag_TokenParser()); 
    
    $template =<<