diff options
Diffstat (limited to 'inc/Twig/TokenParser')
-rw-r--r-- | inc/Twig/TokenParser/AutoEscape.php | 89 | ||||
-rw-r--r-- | inc/Twig/TokenParser/Block.php | 83 | ||||
-rw-r--r-- | inc/Twig/TokenParser/Do.php | 42 | ||||
-rw-r--r-- | inc/Twig/TokenParser/Embed.php | 66 | ||||
-rw-r--r-- | inc/Twig/TokenParser/Extends.php | 52 | ||||
-rw-r--r-- | inc/Twig/TokenParser/Filter.php | 61 | ||||
-rw-r--r-- | inc/Twig/TokenParser/Flush.php | 42 | ||||
-rw-r--r-- | inc/Twig/TokenParser/For.php | 136 | ||||
-rw-r--r-- | inc/Twig/TokenParser/From.php | 74 | ||||
-rw-r--r-- | inc/Twig/TokenParser/If.php | 94 | ||||
-rw-r--r-- | inc/Twig/TokenParser/Import.php | 49 | ||||
-rw-r--r-- | inc/Twig/TokenParser/Include.php | 80 | ||||
-rw-r--r-- | inc/Twig/TokenParser/Macro.php | 68 | ||||
-rw-r--r-- | inc/Twig/TokenParser/Sandbox.php | 68 | ||||
-rw-r--r-- | inc/Twig/TokenParser/Set.php | 84 | ||||
-rw-r--r-- | inc/Twig/TokenParser/Spaceless.php | 59 | ||||
-rw-r--r-- | inc/Twig/TokenParser/Use.php | 82 |
17 files changed, 1229 insertions, 0 deletions
diff --git a/inc/Twig/TokenParser/AutoEscape.php b/inc/Twig/TokenParser/AutoEscape.php new file mode 100644 index 00000000..27560288 --- /dev/null +++ b/inc/Twig/TokenParser/AutoEscape.php | |||
@@ -0,0 +1,89 @@ | |||
1 | <?php | ||
2 | |||
3 | /* | ||
4 | * This file is part of Twig. | ||
5 | * | ||
6 | * (c) 2009 Fabien Potencier | ||
7 | * | ||
8 | * For the full copyright and license information, please view the LICENSE | ||
9 | * file that was distributed with this source code. | ||
10 | */ | ||
11 | |||
12 | /** | ||
13 | * Marks a section of a template to be escaped or not. | ||
14 | * | ||
15 | * <pre> | ||
16 | * {% autoescape true %} | ||
17 | * Everything will be automatically escaped in this block | ||
18 | * {% endautoescape %} | ||
19 | * | ||
20 | * {% autoescape false %} | ||
21 | * Everything will be outputed as is in this block | ||
22 | * {% endautoescape %} | ||
23 | * | ||
24 | * {% autoescape true js %} | ||
25 | * Everything will be automatically escaped in this block | ||
26 | * using the js escaping strategy | ||
27 | * {% endautoescape %} | ||
28 | * </pre> | ||
29 | */ | ||
30 | class Twig_TokenParser_AutoEscape extends Twig_TokenParser | ||
31 | { | ||
32 | /** | ||
33 | * Parses a token and returns a node. | ||
34 | * | ||
35 | * @param Twig_Token $token A Twig_Token instance | ||
36 | * | ||
37 | * @return Twig_NodeInterface A Twig_NodeInterface instance | ||
38 | */ | ||
39 | public function parse(Twig_Token $token) | ||
40 | { | ||
41 | $lineno = $token->getLine(); | ||
42 | $stream = $this->parser->getStream(); | ||
43 | |||
44 | if ($stream->test(Twig_Token::BLOCK_END_TYPE)) { | ||
45 | $value = 'html'; | ||
46 | } else { | ||
47 | $expr = $this->parser->getExpressionParser()->parseExpression(); | ||
48 | if (!$expr instanceof Twig_Node_Expression_Constant) { | ||
49 | throw new Twig_Error_Syntax('An escaping strategy must be a string or a Boolean.', $stream->getCurrent()->getLine(), $stream->getFilename()); | ||
50 | } | ||
51 | $value = $expr->getAttribute('value'); | ||
52 | |||
53 | $compat = true === $value || false === $value; | ||
54 | |||
55 | if (true === $value) { | ||
56 | $value = 'html'; | ||
57 | } | ||
58 | |||
59 | if ($compat && $stream->test(Twig_Token::NAME_TYPE)) { | ||
60 | if (false === $value) { | ||
61 | throw new Twig_Error_Syntax('Unexpected escaping strategy as you set autoescaping to false.', $stream->getCurrent()->getLine(), $stream->getFilename()); | ||
62 | } | ||
63 | |||
64 | $value = $stream->next()->getValue(); | ||
65 | } | ||
66 | } | ||
67 | |||
68 | $stream->expect(Twig_Token::BLOCK_END_TYPE); | ||
69 | $body = $this->parser->subparse(array($this, 'decideBlockEnd'), true); | ||
70 | $stream->expect(Twig_Token::BLOCK_END_TYPE); | ||
71 | |||
72 | return new Twig_Node_AutoEscape($value, $body, $lineno, $this->getTag()); | ||
73 | } | ||
74 | |||
75 | public function decideBlockEnd(Twig_Token $token) | ||
76 | { | ||
77 | return $token->test('endautoescape'); | ||
78 | } | ||
79 | |||
80 | /** | ||
81 | * Gets the tag name associated with this token parser. | ||
82 | * | ||
83 | * @return string The tag name | ||
84 | */ | ||
85 | public function getTag() | ||
86 | { | ||
87 | return 'autoescape'; | ||
88 | } | ||
89 | } | ||
diff --git a/inc/Twig/TokenParser/Block.php b/inc/Twig/TokenParser/Block.php new file mode 100644 index 00000000..a2e017f3 --- /dev/null +++ b/inc/Twig/TokenParser/Block.php | |||
@@ -0,0 +1,83 @@ | |||
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 | /** | ||
26 | * Parses a token and returns a node. | ||
27 | * | ||
28 | * @param Twig_Token $token A Twig_Token instance | ||
29 | * | ||
30 | * @return Twig_NodeInterface A Twig_NodeInterface instance | ||
31 | */ | ||
32 | public function parse(Twig_Token $token) | ||
33 | { | ||
34 | $lineno = $token->getLine(); | ||
35 | $stream = $this->parser->getStream(); | ||
36 | $name = $stream->expect(Twig_Token::NAME_TYPE)->getValue(); | ||
37 | if ($this->parser->hasBlock($name)) { | ||
38 | throw new Twig_Error_Syntax(sprintf("The block '$name' has already been defined line %d", $this->parser->getBlock($name)->getLine()), $stream->getCurrent()->getLine(), $stream->getFilename()); | ||
39 | } | ||
40 | $this->parser->setBlock($name, $block = new Twig_Node_Block($name, new Twig_Node(array()), $lineno)); | ||
41 | $this->parser->pushLocalScope(); | ||
42 | $this->parser->pushBlockStack($name); | ||
43 | |||
44 | if ($stream->test(Twig_Token::BLOCK_END_TYPE)) { | ||
45 | $stream->next(); | ||
46 | |||
47 | $body = $this->parser->subparse(array($this, 'decideBlockEnd'), true); | ||
48 | if ($stream->test(Twig_Token::NAME_TYPE)) { | ||
49 | $value = $stream->next()->getValue(); | ||
50 | |||
51 | if ($value != $name) { | ||
52 | throw new Twig_Error_Syntax(sprintf("Expected endblock for block '$name' (but %s given)", $value), $stream->getCurrent()->getLine(), $stream->getFilename()); | ||
53 | } | ||
54 | } | ||
55 | } else { | ||
56 | $body = new Twig_Node(array( | ||
57 | new Twig_Node_Print($this->parser->getExpressionParser()->parseExpression(), $lineno), | ||
58 | )); | ||
59 | } | ||
60 | $stream->expect(Twig_Token::BLOCK_END_TYPE); | ||
61 | |||
62 | $block->setNode('body', $body); | ||
63 | $this->parser->popBlockStack(); | ||
64 | $this->parser->popLocalScope(); | ||
65 | |||
66 | return new Twig_Node_BlockReference($name, $lineno, $this->getTag()); | ||
67 | } | ||
68 | |||
69 | public function decideBlockEnd(Twig_Token $token) | ||
70 | { | ||
71 | return $token->test('endblock'); | ||
72 | } | ||
73 | |||
74 | /** | ||
75 | * Gets the tag name associated with this token parser. | ||
76 | * | ||
77 | * @return string The tag name | ||
78 | */ | ||
79 | public function getTag() | ||
80 | { | ||
81 | return 'block'; | ||
82 | } | ||
83 | } | ||
diff --git a/inc/Twig/TokenParser/Do.php b/inc/Twig/TokenParser/Do.php new file mode 100644 index 00000000..f50939dd --- /dev/null +++ b/inc/Twig/TokenParser/Do.php | |||
@@ -0,0 +1,42 @@ | |||
1 | <?php | ||
2 | |||
3 | /* | ||
4 | * This file is part of Twig. | ||
5 | * | ||
6 | * (c) 2011 Fabien Potencier | ||
7 | * | ||
8 | * For the full copyright and license information, please view the LICENSE | ||
9 | * file that was distributed with this source code. | ||
10 | */ | ||
11 | |||
12 | /** | ||
13 | * Evaluates an expression, discarding the returned value. | ||
14 | */ | ||
15 | class Twig_TokenParser_Do extends Twig_TokenParser | ||
16 | { | ||
17 | /** | ||
18 | * Parses a token and returns a node. | ||
19 | * | ||
20 | * @param Twig_Token $token A Twig_Token instance | ||
21 | * | ||
22 | * @return Twig_NodeInterface A Twig_NodeInterface instance | ||
23 | */ | ||
24 | public function parse(Twig_Token $token) | ||
25 | { | ||
26 | $expr = $this->parser->getExpressionParser()->parseExpression(); | ||
27 | |||
28 | $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); | ||
29 | |||
30 | return new Twig_Node_Do($expr, $token->getLine(), $this->getTag()); | ||
31 | } | ||
32 | |||
33 | /** | ||
34 | * Gets the tag name associated with this token parser. | ||
35 | * | ||
36 | * @return string The tag name | ||
37 | */ | ||
38 | public function getTag() | ||
39 | { | ||
40 | return 'do'; | ||
41 | } | ||
42 | } | ||
diff --git a/inc/Twig/TokenParser/Embed.php b/inc/Twig/TokenParser/Embed.php new file mode 100644 index 00000000..69cb5f35 --- /dev/null +++ b/inc/Twig/TokenParser/Embed.php | |||
@@ -0,0 +1,66 @@ | |||
1 | <?php | ||
2 | |||
3 | /* | ||
4 | * This file is part of Twig. | ||
5 | * | ||
6 | * (c) 2012 Fabien Potencier | ||
7 | * | ||
8 | * For the full copyright and license information, please view the LICENSE | ||
9 | * file that was distributed with this source code. | ||
10 | */ | ||
11 | |||
12 | /** | ||
13 | * Embeds a template. | ||
14 | */ | ||
15 | class Twig_TokenParser_Embed extends Twig_TokenParser_Include | ||
16 | { | ||
17 | /** | ||
18 | * Parses a token and returns a node. | ||
19 | * | ||
20 | * @param Twig_Token $token A Twig_Token instance | ||
21 | * | ||
22 | * @return Twig_NodeInterface A Twig_NodeInterface instance | ||
23 | */ | ||
24 | public function parse(Twig_Token $token) | ||
25 | { | ||
26 | $stream = $this->parser->getStream(); | ||
27 | |||
28 | $parent = $this->parser->getExpressionParser()->parseExpression(); | ||
29 | |||
30 | list($variables, $only, $ignoreMissing) = $this->parseArguments(); | ||
31 | |||
32 | // inject a fake parent to make the parent() function work | ||
33 | $stream->injectTokens(array( | ||
34 | new Twig_Token(Twig_Token::BLOCK_START_TYPE, '', $token->getLine()), | ||
35 | new Twig_Token(Twig_Token::NAME_TYPE, 'extends', $token->getLine()), | ||
36 | new Twig_Token(Twig_Token::STRING_TYPE, '__parent__', $token->getLine()), | ||
37 | new Twig_Token(Twig_Token::BLOCK_END_TYPE, '', $token->getLine()), | ||
38 | )); | ||
39 | |||
40 | $module = $this->parser->parse($stream, array($this, 'decideBlockEnd'), true); | ||
41 | |||
42 | // override the parent with the correct one | ||
43 | $module->setNode('parent', $parent); | ||
44 | |||
45 | $this->parser->embedTemplate($module); | ||
46 | |||
47 | $stream->expect(Twig_Token::BLOCK_END_TYPE); | ||
48 | |||
49 | return new Twig_Node_Embed($module->getAttribute('filename'), $module->getAttribute('index'), $variables, $only, $ignoreMissing, $token->getLine(), $this->getTag()); | ||
50 | } | ||
51 | |||
52 | public function decideBlockEnd(Twig_Token $token) | ||
53 | { | ||
54 | return $token->test('endembed'); | ||
55 | } | ||
56 | |||
57 | /** | ||
58 | * Gets the tag name associated with this token parser. | ||
59 | * | ||
60 | * @return string The tag name | ||
61 | */ | ||
62 | public function getTag() | ||
63 | { | ||
64 | return 'embed'; | ||
65 | } | ||
66 | } | ||
diff --git a/inc/Twig/TokenParser/Extends.php b/inc/Twig/TokenParser/Extends.php new file mode 100644 index 00000000..f5ecee21 --- /dev/null +++ b/inc/Twig/TokenParser/Extends.php | |||
@@ -0,0 +1,52 @@ | |||
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 | * Extends a template by another one. | ||
15 | * | ||
16 | * <pre> | ||
17 | * {% extends "base.html" %} | ||
18 | * </pre> | ||
19 | */ | ||
20 | class Twig_TokenParser_Extends extends Twig_TokenParser | ||
21 | { | ||
22 | /** | ||
23 | * Parses a token and returns a node. | ||
24 | * | ||
25 | * @param Twig_Token $token A Twig_Token instance | ||
26 | * | ||
27 | * @return Twig_NodeInterface A Twig_NodeInterface instance | ||
28 | */ | ||
29 | public function parse(Twig_Token $token) | ||
30 | { | ||
31 | if (!$this->parser->isMainScope()) { | ||
32 | throw new Twig_Error_Syntax('Cannot extend from a block', $token->getLine(), $this->parser->getFilename()); | ||
33 | } | ||
34 | |||
35 | if (null !== $this->parser->getParent()) { | ||
36 | throw new Twig_Error_Syntax('Multiple extends tags are forbidden', $token->getLine(), $this->parser->getFilename()); | ||
37 | } | ||
38 | $this->parser->setParent($this->parser->getExpressionParser()->parseExpression()); | ||
39 | |||
40 | $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); | ||
41 | } | ||
42 | |||
43 | /** | ||
44 | * Gets the tag name associated with this token parser. | ||
45 | * | ||
46 | * @return string The tag name | ||
47 | */ | ||
48 | public function getTag() | ||
49 | { | ||
50 | return 'extends'; | ||
51 | } | ||
52 | } | ||
diff --git a/inc/Twig/TokenParser/Filter.php b/inc/Twig/TokenParser/Filter.php new file mode 100644 index 00000000..2b97475a --- /dev/null +++ b/inc/Twig/TokenParser/Filter.php | |||
@@ -0,0 +1,61 @@ | |||
1 | <?php | ||
2 | |||
3 | /* | ||
4 | * This file is part of Twig. | ||
5 | * | ||
6 | * (c) 2009 Fabien Potencier | ||
7 | * | ||
8 | * For the full copyright and license information, please view the LICENSE | ||
9 | * file that was distributed with this source code. | ||
10 | */ | ||
11 | |||
12 | /** | ||
13 | * Filters a section of a template by applying filters. | ||
14 | * | ||
15 | * <pre> | ||
16 | * {% filter upper %} | ||
17 | * This text becomes uppercase | ||
18 | * {% endfilter %} | ||
19 | * </pre> | ||
20 | */ | ||
21 | class Twig_TokenParser_Filter extends Twig_TokenParser | ||
22 | { | ||
23 | /** | ||
24 | * Parses a token and returns a node. | ||
25 | * | ||
26 | * @param Twig_Token $token A Twig_Token instance | ||
27 | * | ||
28 | * @return Twig_NodeInterface A Twig_NodeInterface instance | ||
29 | */ | ||
30 | public function parse(Twig_Token $token) | ||
31 | { | ||
32 | $name = $this->parser->getVarName(); | ||
33 | $ref = new Twig_Node_Expression_BlockReference(new Twig_Node_Expression_Constant($name, $token->getLine()), true, $token->getLine(), $this->getTag()); | ||
34 | |||
35 | $filter = $this->parser->getExpressionParser()->parseFilterExpressionRaw($ref, $this->getTag()); | ||
36 | $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); | ||
37 | |||
38 | $body = $this->parser->subparse(array($this, 'decideBlockEnd'), true); | ||
39 | $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); | ||
40 | |||
41 | $block = new Twig_Node_Block($name, $body, $token->getLine()); | ||
42 | $this->parser->setBlock($name, $block); | ||
43 | |||
44 | return new Twig_Node_Print($filter, $token->getLine(), $this->getTag()); | ||
45 | } | ||
46 | |||
47 | public function decideBlockEnd(Twig_Token $token) | ||
48 | { | ||
49 | return $token->test('endfilter'); | ||
50 | } | ||
51 | |||
52 | /** | ||
53 | * Gets the tag name associated with this token parser. | ||
54 | * | ||
55 | * @return string The tag name | ||
56 | */ | ||
57 | public function getTag() | ||
58 | { | ||
59 | return 'filter'; | ||
60 | } | ||
61 | } | ||
diff --git a/inc/Twig/TokenParser/Flush.php b/inc/Twig/TokenParser/Flush.php new file mode 100644 index 00000000..4e15e785 --- /dev/null +++ b/inc/Twig/TokenParser/Flush.php | |||
@@ -0,0 +1,42 @@ | |||
1 | <?php | ||
2 | |||
3 | /* | ||
4 | * This file is part of Twig. | ||
5 | * | ||
6 | * (c) 2011 Fabien Potencier | ||
7 | * | ||
8 | * For the full copyright and license information, please view the LICENSE | ||
9 | * file that was distributed with this source code. | ||
10 | */ | ||
11 | |||
12 | /** | ||
13 | * Flushes the output to the client. | ||
14 | * | ||
15 | * @see flush() | ||
16 | */ | ||
17 | class Twig_TokenParser_Flush extends Twig_TokenParser | ||
18 | { | ||
19 | /** | ||
20 | * Parses a token and returns a node. | ||
21 | * | ||
22 | * @param Twig_Token $token A Twig_Token instance | ||
23 | * | ||
24 | * @return Twig_NodeInterface A Twig_NodeInterface instance | ||
25 | */ | ||
26 | public function parse(Twig_Token $token) | ||
27 | { | ||
28 | $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); | ||
29 | |||
30 | return new Twig_Node_Flush($token->getLine(), $this->getTag()); | ||
31 | } | ||
32 | |||
33 | /** | ||
34 | * Gets the tag name associated with this token parser. | ||
35 | * | ||
36 | * @return string The tag name | ||
37 | */ | ||
38 | public function getTag() | ||
39 | { | ||
40 | return 'flush'; | ||
41 | } | ||
42 | } | ||
diff --git a/inc/Twig/TokenParser/For.php b/inc/Twig/TokenParser/For.php new file mode 100644 index 00000000..98a6d079 --- /dev/null +++ b/inc/Twig/TokenParser/For.php | |||
@@ -0,0 +1,136 @@ | |||
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 | * Loops over each item of a sequence. | ||
15 | * | ||
16 | * <pre> | ||
17 | * <ul> | ||
18 | * {% for user in users %} | ||
19 | * <li>{{ user.username|e }}</li> | ||
20 | * {% endfor %} | ||
21 | * </ul> | ||
22 | * </pre> | ||
23 | */ | ||
24 | class Twig_TokenParser_For extends Twig_TokenParser | ||
25 | { | ||
26 | /** | ||
27 | * Parses a token and returns a node. | ||
28 | * | ||
29 | * @param Twig_Token $token A Twig_Token instance | ||
30 | * | ||
31 | * @return Twig_NodeInterface A Twig_NodeInterface instance | ||
32 | */ | ||
33 | public function parse(Twig_Token $token) | ||
34 | { | ||
35 | $lineno = $token->getLine(); | ||
36 | $stream = $this->parser->getStream(); | ||
37 | $targets = $this->parser->getExpressionParser()->parseAssignmentExpression(); | ||
38 | $stream->expect(Twig_Token::OPERATOR_TYPE, 'in'); | ||
39 | $seq = $this->parser->getExpressionParser()->parseExpression(); | ||
40 | |||
41 | $ifexpr = null; | ||
42 | if ($stream->test(Twig_Token::NAME_TYPE, 'if')) { | ||
43 | $stream->next(); | ||
44 | $ifexpr = $this->parser->getExpressionParser()->parseExpression(); | ||
45 | } | ||
46 | |||
47 | $stream->expect(Twig_Token::BLOCK_END_TYPE); | ||
48 | $body = $this->parser->subparse(array($this, 'decideForFork')); | ||
49 | if ($stream->next()->getValue() == 'else') { | ||
50 | $stream->expect(Twig_Token::BLOCK_END_TYPE); | ||
51 | $else = $this->parser->subparse(array($this, 'decideForEnd'), true); | ||
52 | } else { | ||
53 | $else = null; | ||
54 | } | ||
55 | $stream->expect(Twig_Token::BLOCK_END_TYPE); | ||
56 | |||
57 | if (count($targets) > 1) { | ||
58 | $keyTarget = $targets->getNode(0); | ||
59 | $keyTarget = new Twig_Node_Expression_AssignName($keyTarget->getAttribute('name'), $keyTarget->getLine()); | ||
60 | $valueTarget = $targets->getNode(1); | ||
61 | $valueTarget = new Twig_Node_Expression_AssignName($valueTarget->getAttribute('name'), $valueTarget->getLine()); | ||
62 | } else { | ||
63 | $keyTarget = new Twig_Node_Expression_AssignName('_key', $lineno); | ||
64 | $valueTarget = $targets->getNode(0); | ||
65 | $valueTarget = new Twig_Node_Expression_AssignName($valueTarget->getAttribute('name'), $valueTarget->getLine()); | ||
66 | } | ||
67 | |||
68 | if ($ifexpr) { | ||
69 | $this->checkLoopUsageCondition($stream, $ifexpr); | ||
70 | $this->checkLoopUsageBody($stream, $body); | ||
71 | } | ||
72 | |||
73 | return new Twig_Node_For($keyTarget, $valueTarget, $seq, $ifexpr, $body, $else, $lineno, $this->getTag()); | ||
74 | } | ||
75 | |||
76 | public function decideForFork(Twig_Token $token) | ||
77 | { | ||
78 | return $token->test(array('else', 'endfor')); | ||
79 | } | ||
80 | |||
81 | public function decideForEnd(Twig_Token $token) | ||
82 | { | ||
83 | return $token->test('endfor'); | ||
84 | } | ||
85 | |||
86 | // the loop variable cannot be used in the condition | ||
87 | protected function checkLoopUsageCondition(Twig_TokenStream $stream, Twig_NodeInterface $node) | ||
88 | { | ||
89 | if ($node instanceof Twig_Node_Expression_GetAttr && $node->getNode('node') instanceof Twig_Node_Expression_Name && 'loop' == $node->getNode('node')->getAttribute('name')) { | ||
90 | throw new Twig_Error_Syntax('The "loop" variable cannot be used in a looping condition', $node->getLine(), $stream->getFilename()); | ||
91 | } | ||
92 | |||
93 | foreach ($node as $n) { | ||
94 | if (!$n) { | ||
95 | continue; | ||
96 | } | ||
97 | |||
98 | $this->checkLoopUsageCondition($stream, $n); | ||
99 | } | ||
100 | } | ||
101 | |||
102 | // check usage of non-defined loop-items | ||
103 | // it does not catch all problems (for instance when a for is included into another or when the variable is used in an include) | ||
104 | protected function checkLoopUsageBody(Twig_TokenStream $stream, Twig_NodeInterface $node) | ||
105 | { | ||
106 | if ($node instanceof Twig_Node_Expression_GetAttr && $node->getNode('node') instanceof Twig_Node_Expression_Name && 'loop' == $node->getNode('node')->getAttribute('name')) { | ||
107 | $attribute = $node->getNode('attribute'); | ||
108 | if ($attribute instanceof Twig_Node_Expression_Constant && in_array($attribute->getAttribute('value'), array('length', 'revindex0', 'revindex', 'last'))) { | ||
109 | throw new Twig_Error_Syntax(sprintf('The "loop.%s" variable is not defined when looping with a condition', $attribute->getAttribute('value')), $node->getLine(), $stream->getFilename()); | ||
110 | } | ||
111 | } | ||
112 | |||
113 | // should check for parent.loop.XXX usage | ||
114 | if ($node instanceof Twig_Node_For) { | ||
115 | return; | ||
116 | } | ||
117 | |||
118 | foreach ($node as $n) { | ||
119 | if (!$n) { | ||
120 | continue; | ||
121 | } | ||
122 | |||
123 | $this->checkLoopUsageBody($stream, $n); | ||
124 | } | ||
125 | } | ||
126 | |||
127 | /** | ||
128 | * Gets the tag name associated with this token parser. | ||
129 | * | ||
130 | * @return string The tag name | ||
131 | */ | ||
132 | public function getTag() | ||
133 | { | ||
134 | return 'for'; | ||
135 | } | ||
136 | } | ||
diff --git a/inc/Twig/TokenParser/From.php b/inc/Twig/TokenParser/From.php new file mode 100644 index 00000000..a54054db --- /dev/null +++ b/inc/Twig/TokenParser/From.php | |||
@@ -0,0 +1,74 @@ | |||
1 | <?php | ||
2 | |||
3 | /* | ||
4 | * This file is part of Twig. | ||
5 | * | ||
6 | * (c) 2010 Fabien Potencier | ||
7 | * | ||
8 | * For the full copyright and license information, please view the LICENSE | ||
9 | * file that was distributed with this source code. | ||
10 | */ | ||
11 | |||
12 | /** | ||
13 | * Imports macros. | ||
14 | * | ||
15 | * <pre> | ||
16 | * {% from 'forms.html' import forms %} | ||
17 | * </pre> | ||
18 | */ | ||
19 | class Twig_TokenParser_From extends Twig_TokenParser | ||
20 | { | ||
21 | /** | ||
22 | * Parses a token and returns a node. | ||
23 | * | ||
24 | * @param Twig_Token $token A Twig_Token instance | ||
25 | * | ||
26 | * @return Twig_NodeInterface A Twig_NodeInterface instance | ||
27 | */ | ||
28 | public function parse(Twig_Token $token) | ||
29 | { | ||
30 | $macro = $this->parser->getExpressionParser()->parseExpression(); | ||
31 | $stream = $this->parser->getStream(); | ||
32 | $stream->expect('import'); | ||
33 | |||
34 | $targets = array(); | ||
35 | do { | ||
36 | $name = $stream->expect(Twig_Token::NAME_TYPE)->getValue(); | ||
37 | |||
38 | $alias = $name; | ||
39 | if ($stream->test('as')) { | ||
40 | $stream->next(); | ||
41 | |||
42 | $alias = $stream->expect(Twig_Token::NAME_TYPE)->getValue(); | ||
43 | } | ||
44 | |||
45 | $targets[$name] = $alias; | ||
46 | |||
47 | if (!$stream->test(Twig_Token::PUNCTUATION_TYPE, ',')) { | ||
48 | break; | ||
49 | } | ||
50 | |||
51 | $stream->next(); | ||
52 | } while (true); | ||
53 | |||
54 | $stream->expect(Twig_Token::BLOCK_END_TYPE); | ||
55 | |||
56 | $node = new Twig_Node_Import($macro, new Twig_Node_Expression_AssignName($this->parser->getVarName(), $token->getLine()), $token->getLine(), $this->getTag()); | ||
57 | |||
58 | foreach ($targets as $name => $alias) { | ||
59 | $this->parser->addImportedSymbol('function', $alias, 'get'.$name, $node->getNode('var')); | ||
60 | } | ||
61 | |||
62 | return $node; | ||
63 | } | ||
64 | |||
65 | /** | ||
66 | * Gets the tag name associated with this token parser. | ||
67 | * | ||
68 | * @return string The tag name | ||
69 | */ | ||
70 | public function getTag() | ||
71 | { | ||
72 | return 'from'; | ||
73 | } | ||
74 | } | ||
diff --git a/inc/Twig/TokenParser/If.php b/inc/Twig/TokenParser/If.php new file mode 100644 index 00000000..3d7d1f51 --- /dev/null +++ b/inc/Twig/TokenParser/If.php | |||
@@ -0,0 +1,94 @@ | |||
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 | * Tests a condition. | ||
15 | * | ||
16 | * <pre> | ||
17 | * {% if users %} | ||
18 | * <ul> | ||
19 | * {% for user in users %} | ||
20 | * <li>{{ user.username|e }}</li> | ||
21 | * {% endfor %} | ||
22 | * </ul> | ||
23 | * {% endif %} | ||
24 | * </pre> | ||
25 | */ | ||
26 | class Twig_TokenParser_If extends Twig_TokenParser | ||
27 | { | ||
28 | /** | ||
29 | * Parses a token and returns a node. | ||
30 | * | ||
31 | * @param Twig_Token $token A Twig_Token instance | ||
32 | * | ||
33 | * @return Twig_NodeInterface A Twig_NodeInterface instance | ||
34 | */ | ||
35 | public function parse(Twig_Token $token) | ||
36 | { | ||
37 | $lineno = $token->getLine(); | ||
38 | $expr = $this->parser->getExpressionParser()->parseExpression(); | ||
39 | $stream = $this->parser->getStream(); | ||
40 | $stream->expect(Twig_Token::BLOCK_END_TYPE); | ||
41 | $body = $this->parser->subparse(array($this, 'decideIfFork')); | ||
42 | $tests = array($expr, $body); | ||
43 | $else = null; | ||
44 | |||
45 | $end = false; | ||
46 | while (!$end) { | ||
47 | switch ($stream->next()->getValue()) { | ||
48 | case 'else': | ||
49 | $stream->expect(Twig_Token::BLOCK_END_TYPE); | ||
50 | $else = $this->parser->subparse(array($this, 'decideIfEnd')); | ||
51 | break; | ||
52 | |||
53 | case 'elseif': | ||
54 | $expr = $this->parser->getExpressionParser()->parseExpression(); | ||
55 | $stream->expect(Twig_Token::BLOCK_END_TYPE); | ||
56 | $body = $this->parser->subparse(array($this, 'decideIfFork')); | ||
57 | $tests[] = $expr; | ||
58 | $tests[] = $body; | ||
59 | break; | ||
60 | |||
61 | case 'endif': | ||
62 | $end = true; | ||
63 | break; | ||
64 | |||
65 | default: | ||
66 | throw new Twig_Error_Syntax(sprintf('Unexpected end of template. Twig was looking for the following tags "else", "elseif", or "endif" to close the "if" block started at line %d)', $lineno), $stream->getCurrent()->getLine(), $stream->getFilename()); | ||
67 | } | ||
68 | } | ||
69 | |||
70 | $stream->expect(Twig_Token::BLOCK_END_TYPE); | ||
71 | |||
72 | return new Twig_Node_If(new Twig_Node($tests), $else, $lineno, $this->getTag()); | ||
73 | } | ||
74 | |||
75 | public function decideIfFork(Twig_Token $token) | ||
76 | { | ||
77 | return $token->test(array('elseif', 'else', 'endif')); | ||
78 | } | ||
79 | |||
80 | public function decideIfEnd(Twig_Token $token) | ||
81 | { | ||
82 | return $token->test(array('endif')); | ||
83 | } | ||
84 | |||
85 | /** | ||
86 | * Gets the tag name associated with this token parser. | ||
87 | * | ||
88 | * @return string The tag name | ||
89 | */ | ||
90 | public function getTag() | ||
91 | { | ||
92 | return 'if'; | ||
93 | } | ||
94 | } | ||
diff --git a/inc/Twig/TokenParser/Import.php b/inc/Twig/TokenParser/Import.php new file mode 100644 index 00000000..e7050c70 --- /dev/null +++ b/inc/Twig/TokenParser/Import.php | |||
@@ -0,0 +1,49 @@ | |||
1 | <?php | ||
2 | |||
3 | /* | ||
4 | * This file is part of Twig. | ||
5 | * | ||
6 | * (c) 2009 Fabien Potencier | ||
7 | * | ||
8 | * For the full copyright and license information, please view the LICENSE | ||
9 | * file that was distributed with this source code. | ||
10 | */ | ||
11 | |||
12 | /** | ||
13 | * Imports macros. | ||
14 | * | ||
15 | * <pre> | ||
16 | * {% import 'forms.html' as forms %} | ||
17 | * </pre> | ||
18 | */ | ||
19 | class Twig_TokenParser_Import extends Twig_TokenParser | ||
20 | { | ||
21 | /** | ||
22 | * Parses a token and returns a node. | ||
23 | * | ||
24 | * @param Twig_Token $token A Twig_Token instance | ||
25 | * | ||
26 | * @return Twig_NodeInterface A Twig_NodeInterface instance | ||
27 | */ | ||
28 | public function parse(Twig_Token $token) | ||
29 | { | ||
30 | $macro = $this->parser->getExpressionParser()->parseExpression(); | ||
31 | $this->parser->getStream()->expect('as'); | ||
32 | $var = new Twig_Node_Expression_AssignName($this->parser->getStream()->expect(Twig_Token::NAME_TYPE)->getValue(), $token->getLine()); | ||
33 | $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); | ||
34 | |||
35 | $this->parser->addImportedSymbol('template', $var->getAttribute('name')); | ||
36 | |||
37 | return new Twig_Node_Import($macro, $var, $token->getLine(), $this->getTag()); | ||
38 | } | ||
39 | |||
40 | /** | ||
41 | * Gets the tag name associated with this token parser. | ||
42 | * | ||
43 | * @return string The tag name | ||
44 | */ | ||
45 | public function getTag() | ||
46 | { | ||
47 | return 'import'; | ||
48 | } | ||
49 | } | ||
diff --git a/inc/Twig/TokenParser/Include.php b/inc/Twig/TokenParser/Include.php new file mode 100644 index 00000000..4a317868 --- /dev/null +++ b/inc/Twig/TokenParser/Include.php | |||
@@ -0,0 +1,80 @@ | |||
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 | * Includes a template. | ||
15 | * | ||
16 | * <pre> | ||
17 | * {% include 'header.html' %} | ||
18 | * Body | ||
19 | * {% include 'footer.html' %} | ||
20 | * </pre> | ||
21 | */ | ||
22 | class Twig_TokenParser_Include extends Twig_TokenParser | ||
23 | { | ||
24 | /** | ||
25 | * Parses a token and returns a node. | ||
26 | * | ||
27 | * @param Twig_Token $token A Twig_Token instance | ||
28 | * | ||
29 | * @return Twig_NodeInterface A Twig_NodeInterface instance | ||
30 | */ | ||
31 | public function parse(Twig_Token $token) | ||
32 | { | ||
33 | $expr = $this->parser->getExpressionParser()->parseExpression(); | ||
34 | |||
35 | list($variables, $only, $ignoreMissing) = $this->parseArguments(); | ||
36 | |||
37 | return new Twig_Node_Include($expr, $variables, $only, $ignoreMissing, $token->getLine(), $this->getTag()); | ||
38 | } | ||
39 | |||
40 | protected function parseArguments() | ||
41 | { | ||
42 | $stream = $this->parser->getStream(); | ||
43 | |||
44 | $ignoreMissing = false; | ||
45 | if ($stream->test(Twig_Token::NAME_TYPE, 'ignore')) { | ||
46 | $stream->next(); | ||
47 | $stream->expect(Twig_Token::NAME_TYPE, 'missing'); | ||
48 | |||
49 | $ignoreMissing = true; | ||
50 | } | ||
51 | |||
52 | $variables = null; | ||
53 | if ($stream->test(Twig_Token::NAME_TYPE, 'with')) { | ||
54 | $stream->next(); | ||
55 | |||
56 | $variables = $this->parser->getExpressionParser()->parseExpression(); | ||
57 | } | ||
58 | |||
59 | $only = false; | ||
60 | if ($stream->test(Twig_Token::NAME_TYPE, 'only')) { | ||
61 | $stream->next(); | ||
62 | |||
63 | $only = true; | ||
64 | } | ||
65 | |||
66 | $stream->expect(Twig_Token::BLOCK_END_TYPE); | ||
67 | |||
68 | return array($variables, $only, $ignoreMissing); | ||
69 | } | ||
70 | |||
71 | /** | ||
72 | * Gets the tag name associated with this token parser. | ||
73 | * | ||
74 | * @return string The tag name | ||
75 | */ | ||
76 | public function getTag() | ||
77 | { | ||
78 | return 'include'; | ||
79 | } | ||
80 | } | ||
diff --git a/inc/Twig/TokenParser/Macro.php b/inc/Twig/TokenParser/Macro.php new file mode 100644 index 00000000..82b4fa6d --- /dev/null +++ b/inc/Twig/TokenParser/Macro.php | |||
@@ -0,0 +1,68 @@ | |||
1 | <?php | ||
2 | |||
3 | /* | ||
4 | * This file is part of Twig. | ||
5 | * | ||
6 | * (c) 2009 Fabien Potencier | ||
7 | * | ||
8 | * For the full copyright and license information, please view the LICENSE | ||
9 | * file that was distributed with this source code. | ||
10 | */ | ||
11 | |||
12 | /** | ||
13 | * Defines a macro. | ||
14 | * | ||
15 | * <pre> | ||
16 | * {% macro input(name, value, type, size) %} | ||
17 | * <input type="{{ type|default('text') }}" name="{{ name }}" value="{{ value|e }}" size="{{ size|default(20) }}" /> | ||
18 | * {% endmacro %} | ||
19 | * </pre> | ||
20 | */ | ||
21 | class Twig_TokenParser_Macro extends Twig_TokenParser | ||
22 | { | ||
23 | /** | ||
24 | * Parses a token and returns a node. | ||
25 | * | ||
26 | * @param Twig_Token $token A Twig_Token instance | ||
27 | * | ||
28 | * @return Twig_NodeInterface A Twig_NodeInterface instance | ||
29 | */ | ||
30 | public function parse(Twig_Token $token) | ||
31 | { | ||
32 | $lineno = $token->getLine(); | ||
33 | $stream = $this->parser->getStream(); | ||
34 | $name = $stream->expect(Twig_Token::NAME_TYPE)->getValue(); | ||
35 | |||
36 | $arguments = $this->parser->getExpressionParser()->parseArguments(true, true); | ||
37 | |||
38 | $stream->expect(Twig_Token::BLOCK_END_TYPE); | ||
39 | $this->parser->pushLocalScope(); | ||
40 | $body = $this->parser->subparse(array($this, 'decideBlockEnd'), true); | ||
41 | if ($stream->test(Twig_Token::NAME_TYPE)) { | ||
42 | $value = $stream->next()->getValue(); | ||
43 | |||
44 | if ($value != $name) { | ||
45 | throw new Twig_Error_Syntax(sprintf("Expected endmacro for macro '$name' (but %s given)", $value), $stream->getCurrent()->getLine(), $stream->getFilename()); | ||
46 | } | ||
47 | } | ||
48 | $this->parser->popLocalScope(); | ||
49 | $stream->expect(Twig_Token::BLOCK_END_TYPE); | ||
50 | |||
51 | $this->parser->setMacro($name, new Twig_Node_Macro($name, new Twig_Node_Body(array($body)), $arguments, $lineno, $this->getTag())); | ||
52 | } | ||
53 | |||
54 | public function decideBlockEnd(Twig_Token $token) | ||
55 | { | ||
56 | return $token->test('endmacro'); | ||
57 | } | ||
58 | |||
59 | /** | ||
60 | * Gets the tag name associated with this token parser. | ||
61 | * | ||
62 | * @return string The tag name | ||
63 | */ | ||
64 | public function getTag() | ||
65 | { | ||
66 | return 'macro'; | ||
67 | } | ||
68 | } | ||
diff --git a/inc/Twig/TokenParser/Sandbox.php b/inc/Twig/TokenParser/Sandbox.php new file mode 100644 index 00000000..9457325a --- /dev/null +++ b/inc/Twig/TokenParser/Sandbox.php | |||
@@ -0,0 +1,68 @@ | |||
1 | <?php | ||
2 | |||
3 | /* | ||
4 | * This file is part of Twig. | ||
5 | * | ||
6 | * (c) 2010 Fabien Potencier | ||
7 | * | ||
8 | * For the full copyright and license information, please view the LICENSE | ||
9 | * file that was distributed with this source code. | ||
10 | */ | ||
11 | |||
12 | /** | ||
13 | * Marks a section of a template as untrusted code that must be evaluated in the sandbox mode. | ||
14 | * | ||
15 | * <pre> | ||
16 | * {% sandbox %} | ||
17 | * {% include 'user.html' %} | ||
18 | * {% endsandbox %} | ||
19 | * </pre> | ||
20 | * | ||
21 | * @see http://www.twig-project.org/doc/api.html#sandbox-extension for details | ||
22 | */ | ||
23 | class Twig_TokenParser_Sandbox extends Twig_TokenParser | ||
24 | { | ||
25 | /** | ||
26 | * Parses a token and returns a node. | ||
27 | * | ||
28 | * @param Twig_Token $token A Twig_Token instance | ||
29 | * | ||
30 | * @return Twig_NodeInterface A Twig_NodeInterface instance | ||
31 | */ | ||
32 | public function parse(Twig_Token $token) | ||
33 | { | ||
34 | $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); | ||
35 | $body = $this->parser->subparse(array($this, 'decideBlockEnd'), true); | ||
36 | $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); | ||
37 | |||
38 | // in a sandbox tag, only include tags are allowed | ||
39 | if (!$body instanceof Twig_Node_Include) { | ||
40 | foreach ($body as $node) { | ||
41 | if ($node instanceof Twig_Node_Text && ctype_space($node->getAttribute('data'))) { | ||
42 | continue; | ||
43 | } | ||
44 | |||
45 | if (!$node instanceof Twig_Node_Include) { | ||
46 | throw new Twig_Error_Syntax('Only "include" tags are allowed within a "sandbox" section', $node->getLine(), $this->parser->getFilename()); | ||
47 | } | ||
48 | } | ||
49 | } | ||
50 | |||
51 | return new Twig_Node_Sandbox($body, $token->getLine(), $this->getTag()); | ||
52 | } | ||
53 | |||
54 | public function decideBlockEnd(Twig_Token $token) | ||
55 | { | ||
56 | return $token->test('endsandbox'); | ||
57 | } | ||
58 | |||
59 | /** | ||
60 | * Gets the tag name associated with this token parser. | ||
61 | * | ||
62 | * @return string The tag name | ||
63 | */ | ||
64 | public function getTag() | ||
65 | { | ||
66 | return 'sandbox'; | ||
67 | } | ||
68 | } | ||
diff --git a/inc/Twig/TokenParser/Set.php b/inc/Twig/TokenParser/Set.php new file mode 100644 index 00000000..70e0b41b --- /dev/null +++ b/inc/Twig/TokenParser/Set.php | |||
@@ -0,0 +1,84 @@ | |||
1 | <?php | ||
2 | |||
3 | /* | ||
4 | * This file is part of Twig. | ||
5 | * | ||
6 | * (c) 2009 Fabien Potencier | ||
7 | * | ||
8 | * For the full copyright and license information, please view the LICENSE | ||
9 | * file that was distributed with this source code. | ||
10 | */ | ||
11 | |||
12 | /** | ||
13 | * Defines a variable. | ||
14 | * | ||
15 | * <pre> | ||
16 | * {% set foo = 'foo' %} | ||
17 | * | ||
18 | * {% set foo = [1, 2] %} | ||
19 | * | ||
20 | * {% set foo = {'foo': 'bar'} %} | ||
21 | * | ||
22 | * {% set foo = 'foo' ~ 'bar' %} | ||
23 | * | ||
24 | * {% set foo, bar = 'foo', 'bar' %} | ||
25 | * | ||
26 | * {% set foo %}Some content{% endset %} | ||
27 | * </pre> | ||
28 | */ | ||
29 | class Twig_TokenParser_Set extends Twig_TokenParser | ||
30 | { | ||
31 | /** | ||
32 | * Parses a token and returns a node. | ||
33 | * | ||
34 | * @param Twig_Token $token A Twig_Token instance | ||
35 | * | ||
36 | * @return Twig_NodeInterface A Twig_NodeInterface instance | ||
37 | */ | ||
38 | public function parse(Twig_Token $token) | ||
39 | { | ||
40 | $lineno = $token->getLine(); | ||
41 | $stream = $this->parser->getStream(); | ||
42 | $names = $this->parser->getExpressionParser()->parseAssignmentExpression(); | ||
43 | |||
44 | $capture = false; | ||
45 | if ($stream->test(Twig_Token::OPERATOR_TYPE, '=')) { | ||
46 | $stream->next(); | ||
47 | $values = $this->parser->getExpressionParser()->parseMultitargetExpression(); | ||
48 | |||
49 | $stream->expect(Twig_Token::BLOCK_END_TYPE); | ||
50 | |||
51 | if (count($names) !== count($values)) { | ||
52 | throw new Twig_Error_Syntax("When using set, you must have the same number of variables and assignments.", $stream->getCurrent()->getLine(), $stream->getFilename()); | ||
53 | } | ||
54 | } else { | ||
55 | $capture = true; | ||
56 | |||
57 | if (count($names) > 1) { | ||
58 | throw new Twig_Error_Syntax("When using set with a block, you cannot have a multi-target.", $stream->getCurrent()->getLine(), $stream->getFilename()); | ||
59 | } | ||
60 | |||
61 | $stream->expect(Twig_Token::BLOCK_END_TYPE); | ||
62 | |||
63 | $values = $this->parser->subparse(array($this, 'decideBlockEnd'), true); | ||
64 | $stream->expect(Twig_Token::BLOCK_END_TYPE); | ||
65 | } | ||
66 | |||
67 | return new Twig_Node_Set($capture, $names, $values, $lineno, $this->getTag()); | ||
68 | } | ||
69 | |||
70 | public function decideBlockEnd(Twig_Token $token) | ||
71 | { | ||
72 | return $token->test('endset'); | ||
73 | } | ||
74 | |||
75 | /** | ||
76 | * Gets the tag name associated with this token parser. | ||
77 | * | ||
78 | * @return string The tag name | ||
79 | */ | ||
80 | public function getTag() | ||
81 | { | ||
82 | return 'set'; | ||
83 | } | ||
84 | } | ||
diff --git a/inc/Twig/TokenParser/Spaceless.php b/inc/Twig/TokenParser/Spaceless.php new file mode 100644 index 00000000..1e3fa8f3 --- /dev/null +++ b/inc/Twig/TokenParser/Spaceless.php | |||
@@ -0,0 +1,59 @@ | |||
1 | <?php | ||
2 | |||
3 | /* | ||
4 | * This file is part of Twig. | ||
5 | * | ||
6 | * (c) 2010 Fabien Potencier | ||
7 | * | ||
8 | * For the full copyright and license information, please view the LICENSE | ||
9 | * file that was distributed with this source code. | ||
10 | */ | ||
11 | |||
12 | /** | ||
13 | * Remove whitespaces between HTML tags. | ||
14 | * | ||
15 | * <pre> | ||
16 | * {% spaceless %} | ||
17 | * <div> | ||
18 | * <strong>foo</strong> | ||
19 | * </div> | ||
20 | * {% endspaceless %} | ||
21 | * | ||
22 | * {# output will be <div><strong>foo</strong></div> #} | ||
23 | * </pre> | ||
24 | */ | ||
25 | class Twig_TokenParser_Spaceless extends Twig_TokenParser | ||
26 | { | ||
27 | /** | ||
28 | * Parses a token and returns a node. | ||
29 | * | ||
30 | * @param Twig_Token $token A Twig_Token instance | ||
31 | * | ||
32 | * @return Twig_NodeInterface A Twig_NodeInterface instance | ||
33 | */ | ||
34 | public function parse(Twig_Token $token) | ||
35 | { | ||
36 | $lineno = $token->getLine(); | ||
37 | |||
38 | $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); | ||
39 | $body = $this->parser->subparse(array($this, 'decideSpacelessEnd'), true); | ||
40 | $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); | ||
41 | |||
42 | return new Twig_Node_Spaceless($body, $lineno, $this->getTag()); | ||
43 | } | ||
44 | |||
45 | public function decideSpacelessEnd(Twig_Token $token) | ||
46 | { | ||
47 | return $token->test('endspaceless'); | ||
48 | } | ||
49 | |||
50 | /** | ||
51 | * Gets the tag name associated with this token parser. | ||
52 | * | ||
53 | * @return string The tag name | ||
54 | */ | ||
55 | public function getTag() | ||
56 | { | ||
57 | return 'spaceless'; | ||
58 | } | ||
59 | } | ||
diff --git a/inc/Twig/TokenParser/Use.php b/inc/Twig/TokenParser/Use.php new file mode 100644 index 00000000..bc0e09ef --- /dev/null +++ b/inc/Twig/TokenParser/Use.php | |||
@@ -0,0 +1,82 @@ | |||
1 | <?php | ||
2 | |||
3 | /* | ||
4 | * This file is part of Twig. | ||
5 | * | ||
6 | * (c) 2011 Fabien Potencier | ||
7 | * | ||
8 | * For the full copyright and license information, please view the LICENSE | ||
9 | * file that was distributed with this source code. | ||
10 | */ | ||
11 | |||
12 | /** | ||
13 | * Imports blocks defined in another template into the current template. | ||
14 | * | ||
15 | * <pre> | ||
16 | * {% extends "base.html" %} | ||
17 | * | ||
18 | * {% use "blocks.html" %} | ||
19 | * | ||
20 | * {% block title %}{% endblock %} | ||
21 | * {% block content %}{% endblock %} | ||
22 | * </pre> | ||
23 | * | ||
24 | * @see http://www.twig-project.org/doc/templates.html#horizontal-reuse for details. | ||
25 | */ | ||
26 | class Twig_TokenParser_Use extends Twig_TokenParser | ||
27 | { | ||
28 | /** | ||
29 | * Parses a token and returns a node. | ||
30 | * | ||
31 | * @param Twig_Token $token A Twig_Token instance | ||
32 | * | ||
33 | * @return Twig_NodeInterface A Twig_NodeInterface instance | ||
34 | */ | ||
35 | public function parse(Twig_Token $token) | ||
36 | { | ||
37 | $template = $this->parser->getExpressionParser()->parseExpression(); | ||
38 | $stream = $this->parser->getStream(); | ||
39 | |||
40 | if (!$template instanceof Twig_Node_Expression_Constant) { | ||
41 | throw new Twig_Error_Syntax('The template references in a "use" statement must be a string.', $stream->getCurrent()->getLine(), $stream->getFilename()); | ||
42 | } | ||
43 | |||
44 | $targets = array(); | ||
45 | if ($stream->test('with')) { | ||
46 | $stream->next(); | ||
47 | |||
48 | do { | ||
49 | $name = $stream->expect(Twig_Token::NAME_TYPE)->getValue(); | ||
50 | |||
51 | $alias = $name; | ||
52 | if ($stream->test('as')) { | ||
53 | $stream->next(); | ||
54 | |||
55 | $alias = $stream->expect(Twig_Token::NAME_TYPE)->getValue(); | ||
56 | } | ||
57 | |||
58 | $targets[$name] = new Twig_Node_Expression_Constant($alias, -1); | ||
59 | |||
60 | if (!$stream->test(Twig_Token::PUNCTUATION_TYPE, ',')) { | ||
61 | break; | ||
62 | } | ||
63 | |||
64 | $stream->next(); | ||
65 | } while (true); | ||
66 | } | ||
67 | |||
68 | $stream->expect(Twig_Token::BLOCK_END_TYPE); | ||
69 | |||
70 | $this->parser->addTrait(new Twig_Node(array('template' => $template, 'targets' => new Twig_Node($targets)))); | ||
71 | } | ||
72 | |||
73 | /** | ||
74 | * Gets the tag name associated with this token parser. | ||
75 | * | ||
76 | * @return string The tag name | ||
77 | */ | ||
78 | public function getTag() | ||
79 | { | ||
80 | return 'use'; | ||
81 | } | ||
82 | } | ||