TwigTokenParserCache.php 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. <?php
  2. /**
  3. * @package Grav\Common\Twig
  4. *
  5. * @copyright Copyright (c) 2015 - 2023 Trilby Media, LLC. All rights reserved.
  6. * @license MIT License; see LICENSE file for details.
  7. */
  8. namespace Grav\Common\Twig\TokenParser;
  9. use Grav\Common\Grav;
  10. use Grav\Common\Twig\Node\TwigNodeCache;
  11. use Twig\Token;
  12. use Twig\TokenParser\AbstractTokenParser;
  13. /**
  14. * Adds ability to cache Twig between tags.
  15. *
  16. * {% cache 600 %}
  17. * {{ some_complex_work() }}
  18. * {% endcache %}
  19. *
  20. * Also can provide a unique key for the cache:
  21. *
  22. * {% cache "prefix-"~lang 600 %}
  23. *
  24. * Where the "prefix-"~lang will use a unique key based on the current language. "prefix-en" for example
  25. */
  26. class TwigTokenParserCache extends AbstractTokenParser
  27. {
  28. public function parse(Token $token)
  29. {
  30. $stream = $this->parser->getStream();
  31. $lineno = $token->getLine();
  32. // Parse the optional key and timeout parameters
  33. $defaults = [
  34. 'key' => $this->parser->getVarName() . $lineno,
  35. 'lifetime' => Grav::instance()['cache']->getLifetime()
  36. ];
  37. $key = null;
  38. $lifetime = null;
  39. while (!$stream->test(Token::BLOCK_END_TYPE)) {
  40. if ($stream->test(Token::STRING_TYPE)) {
  41. $key = $this->parser->getExpressionParser()->parseExpression();
  42. } elseif ($stream->test(Token::NUMBER_TYPE)) {
  43. $lifetime = $this->parser->getExpressionParser()->parseExpression();
  44. } else {
  45. throw new \Twig\Error\SyntaxError("Unexpected token type in cache tag.", $token->getLine(), $stream->getSourceContext());
  46. }
  47. }
  48. $stream->expect(Token::BLOCK_END_TYPE);
  49. // Parse the content inside the cache block
  50. $body = $this->parser->subparse([$this, 'decideCacheEnd'], true);
  51. $stream->expect(Token::BLOCK_END_TYPE);
  52. return new TwigNodeCache($body, $key, $lifetime, $defaults, $lineno, $this->getTag());
  53. }
  54. public function decideCacheEnd(Token $token): bool
  55. {
  56. return $token->test('endcache');
  57. }
  58. public function getTag(): string
  59. {
  60. return 'cache';
  61. }
  62. }