Block.php 2.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. <?php
  2. /*
  3. * This file is part of Twig.
  4. *
  5. * (c) 2009 Fabien Potencier
  6. * (c) 2009 Armin Ronacher
  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. * Marks a section of a template as being reusable.
  13. *
  14. * <pre>
  15. * {% block head %}
  16. * <link rel="stylesheet" href="style.css" />
  17. * <title>{% block title %}{% endblock %} - My Webpage</title>
  18. * {% endblock %}
  19. * </pre>
  20. */
  21. class Twig_TokenParser_Block 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. if ($this->parser->hasBlock($name)) {
  36. throw new Twig_Error_Syntax(sprintf("The block '$name' has already been defined line %d", $this->parser->getBlock($name)->getLine()), $lineno);
  37. }
  38. $this->parser->setBlock($name, $block = new Twig_Node_Block($name, new Twig_Node(array()), $lineno));
  39. $this->parser->pushLocalScope();
  40. $this->parser->pushBlockStack($name);
  41. if ($stream->test(Twig_Token::BLOCK_END_TYPE)) {
  42. $stream->next();
  43. $body = $this->parser->subparse(array($this, 'decideBlockEnd'), true);
  44. if ($stream->test(Twig_Token::NAME_TYPE)) {
  45. $value = $stream->next()->getValue();
  46. if ($value != $name) {
  47. throw new Twig_Error_Syntax(sprintf("Expected endblock for block '$name' (but %s given)", $value), $lineno);
  48. }
  49. }
  50. } else {
  51. $body = new Twig_Node(array(
  52. new Twig_Node_Print($this->parser->getExpressionParser()->parseExpression(), $lineno),
  53. ));
  54. }
  55. $stream->expect(Twig_Token::BLOCK_END_TYPE);
  56. $block->setNode('body', $body);
  57. $this->parser->popBlockStack();
  58. $this->parser->popLocalScope();
  59. return new Twig_Node_BlockReference($name, $lineno, $this->getTag());
  60. }
  61. public function decideBlockEnd(Twig_Token $token)
  62. {
  63. return $token->test('endblock');
  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 'block';
  73. }
  74. }