mirror of
https://github.com/getgrav/grav.git
synced 2025-12-05 15:29:57 +01:00
improved the Twig Cache Tag with customizable key (lang specific if needed)
This commit is contained in:
@@ -1,3 +1,9 @@
|
||||
# v1.7.42
|
||||
## mm/dd/2023
|
||||
|
||||
1. [](#improved)
|
||||
* Added the ability to set a configurable 'key' for the Twig Cache Tag: `{% cache 'my-key' 600 %}`
|
||||
|
||||
# v1.7.41.1
|
||||
## 05/10/2023
|
||||
|
||||
|
||||
@@ -10,13 +10,15 @@
|
||||
namespace Grav\Common\Twig\Node;
|
||||
|
||||
use Twig\Compiler;
|
||||
use Twig\Node\Expression\AbstractExpression;
|
||||
use Twig\Node\Node;
|
||||
use Twig\Node\NodeOutputInterface;
|
||||
|
||||
/**
|
||||
* Class TwigNodeCache
|
||||
* @package Grav\Common\Twig\Node
|
||||
*/
|
||||
class TwigNodeCache extends Node
|
||||
class TwigNodeCache extends Node implements NodeOutputInterface
|
||||
{
|
||||
/**
|
||||
* @param string $key unique name for key
|
||||
@@ -25,25 +27,58 @@ class TwigNodeCache extends Node
|
||||
* @param integer $lineno
|
||||
* @param string|null $tag
|
||||
*/
|
||||
public function __construct(string $key, int $lifetime, Node $body, $lineno, $tag = null)
|
||||
public function __construct(Node $body, ?AbstractExpression $key, ?AbstractExpression $lifetime, array $defaults, int $lineno, string $tag)
|
||||
{
|
||||
parent::__construct(array('body' => $body), array( 'key' => $key, 'lifetime' => $lifetime), $lineno, $tag);
|
||||
$nodes = ['body' => $body];
|
||||
|
||||
if ($key !== null) {
|
||||
$nodes['key'] = $key;
|
||||
}
|
||||
|
||||
if ($lifetime !== null) {
|
||||
$nodes['lifetime'] = $lifetime;
|
||||
}
|
||||
|
||||
parent::__construct($nodes, $defaults, $lineno, $tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function compile(Compiler $compiler): void
|
||||
{
|
||||
$boo = $this->getAttribute('key');
|
||||
$compiler->addDebugInfo($this);
|
||||
|
||||
|
||||
// Generate the cache key
|
||||
if ($this->hasNode('key')) {
|
||||
$compiler
|
||||
->write('$key = "twigcache-" . ')
|
||||
->subcompile($this->getNode('key'))
|
||||
->raw(";\n");
|
||||
} else {
|
||||
$compiler
|
||||
->write('$key = ')
|
||||
->string($this->getAttribute('key'))
|
||||
->raw(";\n");
|
||||
}
|
||||
|
||||
// Set the cache timeout
|
||||
if ($this->hasNode('lifetime')) {
|
||||
$compiler
|
||||
->write('$lifetime = ')
|
||||
->subcompile($this->getNode('lifetime'))
|
||||
->raw(";\n");
|
||||
} else {
|
||||
$compiler
|
||||
->write('$lifetime = ')
|
||||
->write($this->getAttribute('lifetime'))
|
||||
->raw(";\n");
|
||||
}
|
||||
|
||||
$compiler
|
||||
->addDebugInfo($this)
|
||||
->write("\$cache = \\Grav\\Common\\Grav::instance()['cache'];\n")
|
||||
->write("\$key = \"twigcache-\" . \"" . $this->getAttribute('key') . "\";\n")
|
||||
->write("\$lifetime = " . $this->getAttribute('lifetime') . ";\n")
|
||||
->write("\$cache_body = \$cache->fetch(\$key);\n")
|
||||
->write("if (\$cache_body === false) {\n")
|
||||
->indent()
|
||||
->write("\\Grav\\Common\\Grav::instance()['debugger']->addMessage(\"Cache Key: \$key, Lifetime: \$lifetime\");\n")
|
||||
->write("ob_start();\n")
|
||||
->indent()
|
||||
->subcompile($this->getNode('body'))
|
||||
@@ -53,6 +88,6 @@ class TwigNodeCache extends Node
|
||||
->write("\$cache->save(\$key, \$cache_body, \$lifetime);\n")
|
||||
->outdent()
|
||||
->write("}\n")
|
||||
->write("echo \$cache_body;\n");
|
||||
->write("echo '' === \$cache_body ? '' : new Markup(\$cache_body, \$this->env->getCharset());\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,6 @@ namespace Grav\Common\Twig\TokenParser;
|
||||
|
||||
use Grav\Common\Grav;
|
||||
use Grav\Common\Twig\Node\TwigNodeCache;
|
||||
use Twig\Error\SyntaxError;
|
||||
use Twig\Token;
|
||||
use Twig\TokenParser\AbstractTokenParser;
|
||||
|
||||
@@ -22,50 +21,54 @@ use Twig\TokenParser\AbstractTokenParser;
|
||||
* {{ some_complex_work() }}
|
||||
* {% endcache %}
|
||||
*
|
||||
* Where the `600` is an optional lifetime in seconds
|
||||
* Also can provide a unique key for the cache:
|
||||
*
|
||||
* {% cache "prefix-"~lang 600 %}
|
||||
*
|
||||
* Where the "prefix-"~lang will use a unique key based on the current language. "prefix-en" for example
|
||||
*/
|
||||
class TwigTokenParserCache extends AbstractTokenParser
|
||||
{
|
||||
/**
|
||||
* @param Token $token
|
||||
* @return TwigNodeCache
|
||||
* @throws SyntaxError
|
||||
*/
|
||||
public function parse(Token $token)
|
||||
{
|
||||
$lineno = $token->getLine();
|
||||
$stream = $this->parser->getStream();
|
||||
$key = $this->parser->getVarName() . $lineno;
|
||||
$lifetime = Grav::instance()['cache']->getLifetime();
|
||||
$lineno = $token->getLine();
|
||||
|
||||
// Check for optional lifetime override
|
||||
if (!$stream->test(Token::BLOCK_END_TYPE)) {
|
||||
$lifetime_expr = $this->parser->getExpressionParser()->parseExpression();
|
||||
$lifetime = $lifetime_expr->getAttribute('value');
|
||||
// Parse the optional key and timeout parameters
|
||||
$defaults = [
|
||||
'key' => $this->parser->getVarName() . $lineno,
|
||||
'lifetime' => Grav::instance()['cache']->getLifetime()
|
||||
];
|
||||
|
||||
$key = null;
|
||||
$lifetime = null;
|
||||
while (!$stream->test(Token::BLOCK_END_TYPE)) {
|
||||
if ($stream->test(Token::STRING_TYPE)) {
|
||||
$key = $this->parser->getExpressionParser()->parseExpression();
|
||||
} elseif ($stream->test(Token::NUMBER_TYPE)) {
|
||||
$lifetime = $this->parser->getExpressionParser()->parseExpression();
|
||||
} else {
|
||||
throw new \Twig\Error\SyntaxError("Unexpected token type in cache tag.", $token->getLine(), $stream->getSourceContext());
|
||||
}
|
||||
}
|
||||
|
||||
$stream->expect(Token::BLOCK_END_TYPE);
|
||||
$body = $this->parser->subparse(array($this, 'decideCacheEnd'), true);
|
||||
|
||||
// Parse the content inside the cache block
|
||||
$body = $this->parser->subparse([$this, 'decideCacheEnd'], true);
|
||||
|
||||
$stream->expect(Token::BLOCK_END_TYPE);
|
||||
|
||||
return new TwigNodeCache($key, $lifetime, $body, $lineno, $this->getTag());
|
||||
return new TwigNodeCache($body, $key, $lifetime, $defaults, $lineno, $this->getTag());
|
||||
}
|
||||
|
||||
/**
|
||||
* Decide if current token marks end of cache block.
|
||||
*
|
||||
* @param Token $token
|
||||
* @return bool
|
||||
*/
|
||||
public function decideCacheEnd(Token $token): bool
|
||||
{
|
||||
return $token->test('endcache');
|
||||
}
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
|
||||
public function getTag(): string
|
||||
{
|
||||
return 'cache';
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user