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
|
# v1.7.41.1
|
||||||
## 05/10/2023
|
## 05/10/2023
|
||||||
|
|
||||||
|
|||||||
@@ -10,13 +10,15 @@
|
|||||||
namespace Grav\Common\Twig\Node;
|
namespace Grav\Common\Twig\Node;
|
||||||
|
|
||||||
use Twig\Compiler;
|
use Twig\Compiler;
|
||||||
|
use Twig\Node\Expression\AbstractExpression;
|
||||||
use Twig\Node\Node;
|
use Twig\Node\Node;
|
||||||
|
use Twig\Node\NodeOutputInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class TwigNodeCache
|
* Class TwigNodeCache
|
||||||
* @package Grav\Common\Twig\Node
|
* @package Grav\Common\Twig\Node
|
||||||
*/
|
*/
|
||||||
class TwigNodeCache extends Node
|
class TwigNodeCache extends Node implements NodeOutputInterface
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @param string $key unique name for key
|
* @param string $key unique name for key
|
||||||
@@ -25,25 +27,58 @@ class TwigNodeCache extends Node
|
|||||||
* @param integer $lineno
|
* @param integer $lineno
|
||||||
* @param string|null $tag
|
* @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
|
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
|
$compiler
|
||||||
->addDebugInfo($this)
|
|
||||||
->write("\$cache = \\Grav\\Common\\Grav::instance()['cache'];\n")
|
->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("\$cache_body = \$cache->fetch(\$key);\n")
|
||||||
->write("if (\$cache_body === false) {\n")
|
->write("if (\$cache_body === false) {\n")
|
||||||
->indent()
|
->indent()
|
||||||
|
->write("\\Grav\\Common\\Grav::instance()['debugger']->addMessage(\"Cache Key: \$key, Lifetime: \$lifetime\");\n")
|
||||||
->write("ob_start();\n")
|
->write("ob_start();\n")
|
||||||
->indent()
|
->indent()
|
||||||
->subcompile($this->getNode('body'))
|
->subcompile($this->getNode('body'))
|
||||||
@@ -53,6 +88,6 @@ class TwigNodeCache extends Node
|
|||||||
->write("\$cache->save(\$key, \$cache_body, \$lifetime);\n")
|
->write("\$cache->save(\$key, \$cache_body, \$lifetime);\n")
|
||||||
->outdent()
|
->outdent()
|
||||||
->write("}\n")
|
->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\Grav;
|
||||||
use Grav\Common\Twig\Node\TwigNodeCache;
|
use Grav\Common\Twig\Node\TwigNodeCache;
|
||||||
use Twig\Error\SyntaxError;
|
|
||||||
use Twig\Token;
|
use Twig\Token;
|
||||||
use Twig\TokenParser\AbstractTokenParser;
|
use Twig\TokenParser\AbstractTokenParser;
|
||||||
|
|
||||||
@@ -22,50 +21,54 @@ use Twig\TokenParser\AbstractTokenParser;
|
|||||||
* {{ some_complex_work() }}
|
* {{ some_complex_work() }}
|
||||||
* {% endcache %}
|
* {% 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
|
class TwigTokenParserCache extends AbstractTokenParser
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* @param Token $token
|
|
||||||
* @return TwigNodeCache
|
|
||||||
* @throws SyntaxError
|
|
||||||
*/
|
|
||||||
public function parse(Token $token)
|
public function parse(Token $token)
|
||||||
{
|
{
|
||||||
$lineno = $token->getLine();
|
|
||||||
$stream = $this->parser->getStream();
|
$stream = $this->parser->getStream();
|
||||||
$key = $this->parser->getVarName() . $lineno;
|
$lineno = $token->getLine();
|
||||||
$lifetime = Grav::instance()['cache']->getLifetime();
|
|
||||||
|
|
||||||
// Check for optional lifetime override
|
// Parse the optional key and timeout parameters
|
||||||
if (!$stream->test(Token::BLOCK_END_TYPE)) {
|
$defaults = [
|
||||||
$lifetime_expr = $this->parser->getExpressionParser()->parseExpression();
|
'key' => $this->parser->getVarName() . $lineno,
|
||||||
$lifetime = $lifetime_expr->getAttribute('value');
|
'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);
|
$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);
|
$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
|
public function decideCacheEnd(Token $token): bool
|
||||||
{
|
{
|
||||||
return $token->test('endcache');
|
return $token->test('endcache');
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public function getTag(): string
|
public function getTag(): string
|
||||||
{
|
{
|
||||||
return 'cache';
|
return 'cache';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user