Cachování celé stránky v presenteru

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
Stepan Kabele
Člen | 3
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

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.