Cachování celé stránky v presenteru
- Stepan Kabele
- Člen | 3
Zkusil jsem rozchodit cachování celé stránky dle staršího návodu https://forum.nette.org/…html-vystupu , ale oboje
<?php
$content = ob_get_flush();
$content = ob_get_clean
?>
jsou vždy prázdné.
Nevíte kde hledat chybu?
Cely kod:
<?php
private $wholePageCacheKey = NULL;
/**
* @return void
*/
protected function startup()
{
parent::startup();
// vytvoříme cache ve jmenném prostoru 'application/output'
// (jméno prostoru je libovolný řetezec)
$cache = NEnvironment::getCache('application/output');
// klíčem bude třeba jméno presenteru a view + obsah parametru id
$key = $this->getName() . ':' . $this->getAction() . '#' . $this->params['id'];
// ověření, zda je položka v keši
if (isset($cache[$key])) {
NDebugger::log('cache ' . $key . ' ANO');
echo $cache[$key]; // vypsat a finíto
$this->terminate();
} else {
NDebugger::log('cache ' . $key . ' NE');
$this->wholePageCacheKey = $key;
ob_start();
}
}
/**
* @param Exception optional catched exception
* @return void
*/
protected function shutdown($exception)
{
if (!is_null($this->wholePageCacheKey)) {
//$content = ob_get_clean();
$content = ob_get_flush();
if ($content) {
echo $content;
$cache = NEnvironment::getCache('application/output');
$cache->save($this->wholePageCacheKey, $content, array(
'expire' => 300, // 300 s = 5 minut
));
NDebugger::log('cache shutdown ' . $this->wholePageCacheKey . ' UKLADAM');
} else
NDebugger::log('cache shutdown ' . $this->wholePageCacheKey . ' NEPODARILO SE ZISKAT CONTENT');
} else
NDebugger::log('cache shutdown NEMAM KEY');
?>
- arron
- Člen | 464
Jestli chceč cache na celé stránky, tak se Ti to IMHO bude daleko líp dělat úplně mimo Nette, třeba v bootstrapu a tak. Načítat framework v případě, že máš kompletní výstup je jenom plýtvání časem a výpočetním zdrojem :-) Pozor ale na to, že to sebou nese pár nepříjemných úskalí (některé věci, třeba odeslané formuláře a další, se nesmí do cache dostat!!
- Majkl578
- Moderator | 1364
Ono totiž ve shutdown ještě není posláno nic na výstup. Tam to pošle
Application až poté, co skončí životní cyklus presenteru.
Co kdybys provedl zpracování např. v eventu Application::$onResponse?
Jinak bys musel cacheovat spuštění Application::run (tj. už v bootstrapu,
popř. si podědit Application a dělat to tam v překryté metodě).
- Stepan Kabele
- Člen | 3
Mocrat dekuju a pomoc, Application::$onResponse zafungovalo. Kdyby nekdo resil neco podobneho prikladam kod.
V prezenteru:
<?php
protected function startup()
{
parent::startup();
// vytvoříme cache ve jmenném prostoru 'wholePageCache'
$cache = NEnvironment::getCache('wholePageCache');
$key = $this->getName() . ':' . $this->getAction() . '#' . $this->params['id'];
if ($key != 'Homepage:default#') // cachuju jen default action bez parametru
return;
if (isset($cache[$key])) {
echo $cache[$key]; // vypsat a ukoncit
$this->terminate();
} else {
// nastavuji variable - v Application::onResponse se nacachuje - viz. cacheWholePages() v bootstrap.php
NEnvironment::setVariable('wholePageCacheKey',$key);
}
}
?>
V bootstrapu:
<?php
// Caching whole pages
function cacheWholePages($this, $response) {
$variables = NEnvironment::getVariables();
if (!isset($variables['wholePageCacheKey']))
return;
$key = $variables['wholePageCacheKey'];
$source = $response->getSource();
if ($source instanceof ITemplate) { // template must be rendered
ob_start();
$source->render();
$response = ob_get_flush();
}else
$response = $source;
$cache = NEnvironment::getCache('wholePageCache');
$cache->save($key, $response, array(
'expire' => 300, // 300 s = 5 minut
));
}
$application->onResponse[] = 'cacheWholePages';
$application->run();
?>
…myslel jsem si ze misto ob_get_flush ma byt ob_get_clean (applikace vola render), ale zda se ze je v Nette nejaka ochrana proti opakovanemu renderovani.