Block.php 2.4KB

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("The block '$name' has already been defined", $lineno);
  37. }
  38. $this->parser->pushLocalScope();
  39. $this->parser->pushBlockStack($name);
  40. if ($stream->test(Twig_Token::BLOCK_END_TYPE)) {
  41. $stream->next();
  42. $body = $this->parser->subparse(array($this, 'decideBlockEnd'), true);
  43. if ($stream->test(Twig_Token::NAME_TYPE)) {
  44. $value = $stream->next()->getValue();
  45. if ($value != $name) {
  46. throw new Twig_Error_Syntax(sprintf("Expected endblock for block '$name' (but %s given)", $value), $lineno);
  47. }
  48. }
  49. } else {
  50. $body = new Twig_Node(array(
  51. new Twig_Node_Print($this->parser->getExpressionParser()->parseExpression(), $lineno),
  52. ));
  53. }
  54. $stream->expect(Twig_Token::BLOCK_END_TYPE);
  55. $block = new Twig_Node_Block($name, $body, $lineno);
  56. $this->parser->setBlock($name, $block);
  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. }