Chyby v Cache
- timbulko
- Člen | 85
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
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.
- Jan Tvrdík
- Nette guru | 2595
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.
- Michalek
- Člen | 211
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
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"}
- Jan Tvrdík
- Nette guru | 2595
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
@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á.
- jansfabik
- Člen | 193
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
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
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
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
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}