Závislost templatePrepareFilters() na presenteru
- bojovyletoun
- Člen | 667
Ahoj, přišel jsem na jeden BC break při používání komponent bez presenteru. Původně jsem chtěl napsat nadpis závislost komponent na presenteru, ale to se mi zdálo takové bulvární. Možná se použití komponent bez presenteru bude na první pohled zdát nemožné a nesmysl, ale zde mám příklad. Možná se to otevře nová diskuze o právě této možná zákeřné závislosti.
Ukázka: Používám RssControl pro jednoduché výtahy dat. Jde jen o jednoduchý jednosouborový skript, kde nepoužívám ani Container (ani configurator ani presenter)
include 'nette';
include 'rsscontrol';
Debugger::enable();
//nastavení content type app/xml
$rss = new RssControl();
$rss->items=json_decode(curl_exec($bla));
$rss->render();
//Nette\InvalidStateException
//Component '' is not attached to 'Nette\Application\UI\Presenter
Zde je commit změny
Control::templatePrepareFilters() – kde není hardcoded
new Engine
, ale latte si získá
přes $this->getPresenter()->getContext()->nette->createLatte()
EDIT: Spíš se neptám na řeší, které jsem už našel,
ale o tomto problému v nette samotném
Proto se chci zeptat, jak to vyřešit v nette a udělat komponenty méně
závislé na presenteru. Tohle neplatí doslova, mm teď na mysli právě
ty případy, kdy zádný presenter neexistuje, natož container.
- Je správná cesta upravit Control, aby fungovala i bez přítomnosti presenteru (tzn Registruj latte, jen když existuje presenter)? Tedy pokud komponenta nemá presenter, tak holt filtr zaregistruji ručně? Možná se tu control nebude týkat jen templatepreparefilters.
- něco jiného?
taky mě napadly ohavné řešení antipatternovské:
- kombinace obou, tedy pokud není presenter, navtrdo new Latte, jinak přes
lattefactroy
míru magie posuďte
public function templatePrepareFilters($template)
{
if($p = $this->getPresenter(FALSE))
$template->registerFilter($p->getContext()->nette->createLatte());
else
$template->registerFilter(new \Nette\Latte\Engine());
}
- dědit RssControl
- otázka mimo: měl by se předávat komponentám context. diskutovalo se o tom??
PS: vyřešil jsem to malým hackem, kdy jsem defacto u templaty vymazal ten callback, který se vytvoří v createTemplate, a přepsal svým polem callbacků. Ale přesto si myslím, že tato diskuze bude užitečná a možná odstraní některá WTF při používání komponent standalone.
// tentokrát nikoliv onPrepareFilters[] = function(){};
$rss->template->onPrepareFilters = array(function (Nette\Templating\Template $t) {
$t->registerFilter(new \Nette\Latte\Engine());
});
Editoval bojovyletoun (3. 2. 2012 16:29)