Chyby v Cache

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

Zdravím,
myslím, že som narazil na dve chyby v Nette Cache.

V šablóne, pri použití makra {cache}, ktorý sa nachádza v nejakom cykle (for, foreach, …) sa zobrazuje stále to isté.
Príklad – zobrazí 10 krát to isté číslo:

{for $i=0;$i<10;$i++}
	{cache}
		<?= rand(0,99999); ?><br />
	{/cache}
{/for}

Ďalšia „chyba“ sa týka n: syntaxe pri použítí cache. Keď totiž použijem n:cache=„‚parameter1‘, ‚parameter2‘“, musím tam všade dávať dvojité úvodzovky, čo mi príde trochu zvláštne.

Editoval timbulko (30. 10. 2009 10:53)

Honza Marek
Člen | 1664
+
0
-

První „chyba“ je způsobená tím, že kešovacím klíčem je hash názvu souboru a řádky nebo něco takového.

timbulko
Člen | 85
+
0
-

Aha, no to je škoda, že to funguje takto. Tým pádom nefunguje ani cachovanie vo vnútri komponent (resp. nejde potom tá komponenta použiť viac krát).

Jan Tvrdík
Nette guru | 2595
+
0
-

Makro cache je, jak by řekl Inza, FAIL! Jeho použití je velmi omezené. Někde na fóru lze dohledat xcache. Pokud ho dokážete přepsat na aktuální verzi Nette, tak by mělo jít použít.

redhead
Člen | 1313
+
0
-

David někde psal, že se bude přepisovat, ovšem je to už tak měsíc, a furt nic..

Michalek
Člen | 211
+
0
-

Osobně mám zavedené {scache}, v BasePresenteru ve startupu

LatteMacros::$defaultMacros['scache'] = '<?php if ($_cb->foo = CachingHelper::create($_cb->key = %%, $template->getFile(), array(%%))) { $_cb->caches[] = $_cb->foo ?>';
LatteMacros::$defaultMacros['/scache'] = '<?php array_pop($_cb->caches)->save(); } if (!empty($_cb->caches)) end($_cb->caches)->addItem($_cb->key) ?>';

v šabloně pak

{scache 'clanek#'.$id}
	<h3>{$title}</h3>
	{!$content|texy}
{/scache}

a v presenteru mohu existenci cache kontrolovat přes

$this->cacheTemplate = Environment::getCache('Nette.Template.Curly');
$id = $this->getParam('id');
$this->template->id = $id;
if(!isset($this->cacheTemplate['clanek#' . $id]))
{
	$values = $this->db->select($id)->fetch();
	$this->template->title = $values['nazev_cs'];
	$this->template->content = $values['obsah_cs'];
}

Jestli je to dobře nevím, ale dělá to to co chci a funguje to.

Editoval Michalek (30. 10. 2009 20:03)

David Grudl
Nette Core | 8228
+
0
-

Klíčovou otázkou je, co by měl být klíč cache – v současnosti je to název souboru šablony a řádek. To by dle mého mělo zůstat (řádek možná nahradit čítačem), každý blok cache je tak jedinečný. Nicméně ostatní parametry by měly umět tento klíč rozšiřovat. Pak by stačilo psát {cache $id}...{/cache}.

Tahle změna ale nebude zpětně kompatibilní. Zachovat i podporu pro tagy? Pak to chce vymyslet syntax. Možná by šlo něco jako {cache $id, Cache::TAGS => "clanek/$id"}

Aurielle
Člen | 1281
+
0
-

Možná trochu OT, ale… nebylo by možné, aby metoda $cache->save() brala jako název cache klíče i int? (je to má lenost přetypovávat id z databáze na string před tím, než je uložím do cache)

David Grudl
Nette Core | 8228
+
0
-

Int by to brát mohlo.

Jan Tvrdík
Nette guru | 2595
+
0
-

Možná by šlo něco jako {cache $id, Cache::TAGS => "clanek/$id"}

To vypadá dobře. Osobně věřím, že rozšíření makra cache o parametr ovlivňující klíč povede k hojnému používání tohoto makra.

Honza Kuchař
Člen | 1662
+
0
-

@Honza: Osobně věřím, že rozšíření makra cache o parametr ovlivňující klíč povede k hojnému používání tohoto makra.

Já také, protože v současné době ho tedy moc lidí nepoužívá.

Ozzy
Člen | 2
+
0
-

Rozhodně by se něco takového hodilo.

timbulko
Člen | 85
+
0
-

Ako to v súčastnosti vyzerá s tým cache? Kedy bude možné používať spomínanú novú syntax, ktorá nebude závislá od konkrétneho riadku v súbore?

jansfabik
Člen | 193
+
0
-

Bude se teda to cachovací makro měnit? Ani ve verzi 1.0 se to zatím nezměnilo.

Majkl578
Moderator | 1364
+
0
-

Přidávám se k požadavku.

jansfabik
Člen | 193
+
0
-

Tak zatím to asi budu muset řešit tímto způsobem:

abstract class BasePresenter extends Presenter
{
    public function templatePrepareFilters($template)
    {
        parent::templatePrepareFilters($template);

        LatteMacros::$defaultMacros['cache'] = '<?php if ($_cb->foo = CachingHelper::create($_cb->key = md5(__FILE__) . __LINE__ . implode(\'#\', array(%%)), $template->getFile(), array(%%))) { $_cb->caches[] = $_cb->foo ?>';
    }
}

ale byl bych rád, kdyby se to změnilo v jedničkové verzi frameworku.

Jan Tvrdík
Nette guru | 2595
+
0
-

David Grudl napsal(a):

Pak by stačilo psát {cache $id}...{/cache}. Zachovat i podporu pro tagy?

Bez tagů to asi nepůjde, nebo existuje jiný způsob, jak cache smazat?

David Grudl
Nette Core | 8228
+
0
-

V distribuci je docela nová implementace keše {cache}. Lze ji používat takto:

{cache $id, expire => '+20 minutes', tags => array(tag1, tag2)}
...
{/cache}

Samozřejmě všechny položky jsou volitelné, takže nemusím uvádět ani expiraci, ani tagy, nakonec ani vstupní podmínky (tedy třeba parametr $id). Podmínek je možné uvést i více, oddělených čárkou.

Automaticky se invaliduje při změně souboru. Pokud je uvnitř bloku {cache}...{/cache} vnořený jiný kešovaný blok a ten zneplatníme (například tagem), zneplatní se i blok nadřazaný. Také pokud je uvnitř bloku inkludovaná jiná šablona makrem {include}, její změna způsobí zneplatnění keše.

Ani
Člen | 226
+
0
-

Při použití cache nefunguje ajax, sice se to při odeslání překreslý jak má, ale při dalším načtení je cahce prázdná (soubor je, ale je prázdný).

Stejnou chybu mělo i to řešení od Michalek tady ve vlákně, ale tam jsem si to ošetřil přidnáním podmínky if (!$template->presenter->isAjax()) před array_pop($_cb->caches)->save(); ale to mi u toho nového řešení nefunguje.

e: Tak už mi to funguje s tou podmínkou.

Editoval Ani (26. 8. 2010 20:36)

David Grudl
Nette Core | 8228
+
0
-

A co tam používáš, že při AJAXu to generuje jinou (prázdnou) stránku? Nebylo by pak lepší použít přítomnost AJAXu jako podmínku, tj. {cache $presenter->ajax}...{/cache}