Závislost templatePrepareFilters() na presenteru

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

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.

  1. 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.
  2. něco jiného?

taky mě napadly ohavné řešení antipatternovské:

  1. 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());
}
  1. dědit RssControl

  1. 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)