Project

General

Profile

1
<?php
2

    
3
/*
4
 * This file is part of Twig.
5
 *
6
 * (c) 2009 Fabien Potencier
7
 * (c) 2009 Armin Ronacher
8
 *
9
 * For the full copyright and license information, please view the LICENSE
10
 * file that was distributed with this source code.
11
 */
12

    
13
/**
14
 * Marks a section of a template as being reusable.
15
 *
16
 * <pre>
17
 *  {% block head %}
18
 *    <link rel="stylesheet" href="style.css" />
19
 *    <title>{% block title %}{% endblock %} - My Webpage</title>
20
 *  {% endblock %}
21
 * </pre>
22
 */
23
class Twig_TokenParser_Block extends Twig_TokenParser
24
{
25
    public function parse(Twig_Token $token)
26
    {
27
        $lineno = $token->getLine();
28
        $stream = $this->parser->getStream();
29
        $name = $stream->expect(Twig_Token::NAME_TYPE)->getValue();
30
        if ($this->parser->hasBlock($name)) {
31
            throw new Twig_Error_Syntax(sprintf("The block '%s' has already been defined line %d.", $name, $this->parser->getBlock($name)->getLine()), $stream->getCurrent()->getLine(), $stream->getFilename());
32
        }
33
        $this->parser->setBlock($name, $block = new Twig_Node_Block($name, new Twig_Node(array()), $lineno));
34
        $this->parser->pushLocalScope();
35
        $this->parser->pushBlockStack($name);
36

    
37
        if ($stream->nextIf(Twig_Token::BLOCK_END_TYPE)) {
38
            $body = $this->parser->subparse(array($this, 'decideBlockEnd'), true);
39
            if ($token = $stream->nextIf(Twig_Token::NAME_TYPE)) {
40
                $value = $token->getValue();
41

    
42
                if ($value != $name) {
43
                    throw new Twig_Error_Syntax(sprintf('Expected endblock for block "%s" (but "%s" given).', $name, $value), $stream->getCurrent()->getLine(), $stream->getFilename());
44
                }
45
            }
46
        } else {
47
            $body = new Twig_Node(array(
48
                new Twig_Node_Print($this->parser->getExpressionParser()->parseExpression(), $lineno),
49
            ));
50
        }
51
        $stream->expect(Twig_Token::BLOCK_END_TYPE);
52

    
53
        $block->setNode('body', $body);
54
        $this->parser->popBlockStack();
55
        $this->parser->popLocalScope();
56

    
57
        return new Twig_Node_BlockReference($name, $lineno, $this->getTag());
58
    }
59

    
60
    public function decideBlockEnd(Twig_Token $token)
61
    {
62
        return $token->test('endblock');
63
    }
64

    
65
    public function getTag()
66
    {
67
        return 'block';
68
    }
69
}
(2-2/17)