Created
November 29, 2012 12:03
-
-
Save bwaidelich/4168523 to your computer and use it in GitHub Desktop.
Cache View Helper for TYPO3 Fluid
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Your_Package_ViewHelpers_CacheViewHelper_CacheFrontend: | |
frontend: TYPO3\Flow\Cache\Frontend\StringFrontend | |
backend: TYPO3\Flow\Cache\Backend\SimpleFileBackend |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Your\Package\ViewHelpers; | |
/* * | |
* This script belongs to the TYPO3 Flow package "Your.Package". * | |
* * | |
* It is free software; you can redistribute it and/or modify it under * | |
* the terms of the GNU Lesser General Public License, either version 3 * | |
* of the License, or (at your option) any later version. * | |
* * | |
* The TYPO3 project - inspiring people to share! * | |
* */ | |
use TYPO3\Flow\Annotations as Flow; | |
/** | |
* View Helper that caches all its contents based on a specified identifier | |
* and some (optional) variables | |
* | |
* = Examples = | |
* | |
* <code title="Simple Cache w/o variables"> | |
* <x:cache identifier="foo">This is cached</x:cache> | |
* </code> | |
* <output> | |
* This is cached | |
* </output> | |
* | |
* <code title="Simple Cache w/o variables"> | |
* <x:cache identifier="foo" variables="{bar: bar}">This is cached: {bar}</x:cache> | |
* </code> | |
* <output> | |
* This is cached: <bar> | |
* // depending on {bar} | |
* </output> | |
*/ | |
class CacheViewHelper extends \TYPO3\Fluid\Core\ViewHelper\AbstractViewHelper { | |
/** | |
* @Flow\Inject | |
* @var \TYPO3\Flow\Persistence\PersistenceManagerInterface | |
*/ | |
protected $persistenceManager; | |
/** | |
* @Flow\Inject | |
* @var \TYPO3\Flow\Cache\Frontend\StringFrontend | |
*/ | |
protected $cacheFrontend; | |
/** | |
* @param string $identifier unique identifier for the cache | |
* @param array $variables variables that affect the cache identifier | |
* @return string | |
*/ | |
public function render($identifier, array $variables = array()) { | |
$cacheIdentifier = $this->buildCacheIdentifier(); | |
if (!$this->cacheFrontend->has($cacheIdentifier)) { | |
$content = $this->renderChildren(); | |
$this->cacheFrontend->set($cacheIdentifier, $content); | |
return $content; | |
} | |
return $this->cacheFrontend->get($cacheIdentifier); | |
} | |
/** | |
* @return string | |
*/ | |
protected function buildCacheIdentifier() { | |
$variables = $this->convertObjectsToHashes($this->arguments['variables']); | |
\TYPO3\Flow\Utility\Arrays::sortKeysRecursively($variables); | |
return md5(sprintf('%s|%s', $this->arguments['identifier'], http_build_query($variables))); | |
} | |
/** | |
* Recursively converts objects in an array to their identifiers | |
* | |
* @param array $values the array to be processed | |
* @return array the modified array | |
* @throws \TYPO3\Fluid\Core\ViewHelper\Exception if $values contain an object and its identifier could not be determined | |
*/ | |
protected function convertObjectsToHashes(array $values) { | |
foreach ($values as &$value) { | |
if (is_object($value)) { | |
$identifier = $this->persistenceManager->getIdentifierByObject($value); | |
if ($identifier === NULL) { | |
throw new \TYPO3\Fluid\Core\ViewHelper\Exception(sprintf('The identifier of an object of type "%s" could not be determined', get_class($value)), 1354187274); | |
} | |
$value = $identifier; | |
} elseif (is_array($value)) { | |
$value = $this->convertObjectsToHashes($value); | |
} | |
} | |
return $values; | |
} | |
} | |
?> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{namespace x=Your\Package\ViewHelpers} | |
<h2>non cached</h2> | |
<p>{now -> f:format.date(format: 'd.m.Y H:i:s')}</p> | |
<h2>cached (w/o invalidators)</h2> | |
<x:cache identifier="example1"> | |
<p>{now -> f:format.date(format: 'd.m.Y H:i:s')}</p> | |
</x:cache> | |
<h2>cached (w invalidators)</h2> | |
<x:cache identifier="example2" variables="{foo: foo}"> | |
<p>{now -> f:format.date(format: 'd.m.Y H:i:s')}</p> | |
</x:cache> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Your\Package\ViewHelpers\CacheViewHelper: | |
properties: | |
cacheFrontend: | |
object: | |
factoryObjectName: TYPO3\Flow\Cache\CacheManager | |
factoryMethodName: getCache | |
arguments: | |
1: | |
value: Your_Package_ViewHelpers_CacheViewHelper_CacheFrontend |
FYI: see https://review.typo3.org/#/c/16856/ for a work-in-progress of the cacheable partial implementation. Feel free to add comments on http://forge.typo3.org/issues/43457
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I didn't find a way to avoid the manual identifier which is quite annoying (the ViewHelper instance doesn't have a unique id that survives the session).
Using the hashed raw content in addition to the variables won't work performance wise..
Ultimately, cacheable Partials/Sections are the way to go as they're unique through their path. Stay tuned