-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Expand file tree
/
Copy pathBlockTokenParser.php
More file actions
88 lines (77 loc) · 2.51 KB
/
BlockTokenParser.php
File metadata and controls
88 lines (77 loc) · 2.51 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
<?php
/*
* This file is part of Twig.
*
* (c) Fabien Potencier
* (c) Armin Ronacher
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Twig\TokenParser;
use Twig\Error\SyntaxError;
use Twig\Node\BlockNode;
use Twig\Node\BlockReferenceNode;
use Twig\Node\EmptyNode;
use Twig\Node\Node;
use Twig\Node\Nodes;
use Twig\Node\PrintNode;
use Twig\Token;
/**
* Marks a section of a template as being reusable.
*
* {% block head %}
* <link rel="stylesheet" href="style.css" />
* <title>{% block title %}{% endblock %} - My Webpage</title>
* {% endblock %}
*
* @internal
*/
final class BlockTokenParser extends AbstractTokenParser
{
public function parse(Token $token): Node
{
$lineno = $token->getLine();
$stream = $this->parser->getStream();
$name = $stream->expect(Token::NAME_TYPE)->getValue();
$this->parser->setBlock($name, $block = new BlockNode($name, new EmptyNode(), $lineno));
$this->parser->pushLocalScope();
$this->parser->pushBlockStack($name);
// Check for optional docs="..." attribute
$docs = null;
if ($stream->test(Token::NAME_TYPE, 'docs')) {
$stream->next();
$stream->expect(Token::OPERATOR_TYPE, '=');
$docs = $stream->expect(Token::STRING_TYPE)->getValue();
}
if ($stream->nextIf(Token::BLOCK_END_TYPE)) {
$body = $this->parser->subparse([$this, 'decideBlockEnd'], true);
if ($token = $stream->nextIf(Token::NAME_TYPE)) {
$value = $token->getValue();
if ($value != $name) {
throw new SyntaxError(\sprintf('Expected endblock for block "%s" (but "%s" given).', $name, $value), $stream->getCurrent()->getLine(), $stream->getSourceContext());
}
}
} else {
$body = new Nodes([
new PrintNode($this->parser->parseExpression(), $lineno),
]);
}
$stream->expect(Token::BLOCK_END_TYPE);
$block->setNode('body', $body);
if (null !== $docs) {
$block->setAttribute('docs', $docs);
}
$this->parser->popBlockStack();
$this->parser->popLocalScope();
return new BlockReferenceNode($name, $lineno);
}
public function decideBlockEnd(Token $token): bool
{
return $token->test('endblock');
}
public function getTag(): string
{
return 'block';
}
}