Control a createTemplate

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

Pro vytváření šablon pro komponenty používám $this->getPresenter()->createTemplate(), chtěl bych mít totiž všechny soubory šablon pohromadě – a registrace helperů a filtrů měla pak logicky měla být na jednom místě. Jenže takhle se mi {link signal!} přeloží jako signál na presenter, ne komponentu.

Můžu s tím něco dělat?

Nilp
Člen | 65
+
0
-

Tak jsem to nakonec vyřešil metodou public function setupTemplate(Template $template) v BasePresenteru, a zdá se, že vše funguje.

Editoval Nilp (11. 5. 2009 14:15)

vlki
Člen | 218
+
0
-

Problém je v tom, že pokud vytvoříš šablonu v komponentě z presenteru, bude vlastník té šablony ten presenter. V šabloně to pak dopadne tak, že proměnné $component a $control jsou ekvivalentní s $presenter. Což je v tvém případě nežádoucí.

Tento problém osobně řeším tak, že mám poděděnou třídu Control a tu mám upravenou k obrazu svému – v metodě createTemplate doplněné registrace filtrů a helperů.

Je to nevýhoda, že to je na dvou místech (BasePresenter a BaseControl), ale funkčně je to bez problému.

Možná by nebylo špatné, kdyby byla možnost nastavit filtry a helpery do balíčků, které by se pak aplikovaly. Něco jako jmenný prostor. Existoval by výchozí a šel by změnit. A v tom jmenném prostoru by se daly tyto věci definovat. Umožnilo by to také jednoduché rozšíření takového nastavení do configu.

Co si o tom myslíte?

Honza Marek
Člen | 1664
+
0
-

Přesně tak… určitě bych byl pro to, aby mohly být defaultní filtry a helpery nějakým způsobem na jednom místě nastavené. Šablony bych ocenil i v jiných třídách než v controlech, například mailer nebo nějaký formulářový renderer… Teď je docela komplikované zajistit všude nastavené základní helpery a filtry.

<?php
// ocenil bych něco takového
Template::$defaultHelpers["name"] = "callback";
?>
Jod
Člen | 701
+
0
-

Aj defaultFilters by nebolo na škodu :D

Ondřej Mirtes
Člen | 1536
+
0
-

Já si vytvořil static metodu getEnrichedTemplate(ITemplate $template) a dal jí do BaseControlu. createTemplate() z BaseControlu jí přímo využívá a pro Presentery jí volám v beforeRender BasePresenteru. Pokud máte někdo elegantnější řešení, sem s ním :)

abstract class BaseControl extends Control {

    public function createTemplate() {
        return BaseControl::getEnrichedTemplate(parent::createTemplate());
    }

    public static function getEnrichedTemplate(ITemplate $template) {
        $template->registerFilter('CurlyBracketsFilter::invoke');

	//Helpers registering
        $template->registerHelper('texy', array(Factories::getTexy(), 'process'));
        $template->registerHelper('texyPublic', array(Factories::getTexy(true), 'process'));
        $template->registerHelper('time', 'Helpers::timeHelper');

        return $template;
    }

}
abstract class BasePresenter extends Presenter {
  ...
  public function beforeRender() {
    BaseControl::getEnrichedTemplate($this->template);
  ...
  }
  ...
}

Jak to teď po sobě čtu, asi bych měl to Factories::getTexy() (obdoba toho obohacovače šablon, vrací mi instanci Texy s mým nastavením) měl vyšoupnout mimo parametr té metody do $texy proměnné, takhle se při každém volání tvoří nová instance Texy, takže záhul pro server. Nebo ne?

Editoval LastHunter (11. 5. 2009 16:45)

David Grudl
Nette Core | 8144
+
0
-

Vyvaroval bych se závislostí na vyšší úrovně hierarchie stromu komponent. Metody getParent() nebo getPresenter() by se měly používat velmi opatrně.

Důležitým rysem frameworku je totiž podpora komponent jakožto jednotek znovupoužitelnosti. Pokud bude komponenta závislá na speciálním rozšíření presenteru nebo nějaké statické proměnné, přestává být znovupoužitelná. Pokud bych měl třeba dvě takto napsané komponenty a každá by spoléhala na jiné nastavení (např. Template::$defaultHelpers), nemohl bych je v jedné aplikaci vůbec společně používat.

Nastavení výchozích filtrů jsem se pokusil před nějakou dobou zjednodušit, v podstatě stačí

$template->registerHelperLoader('Nette\Templates\TemplateHelpers::loader');

Neregistruje to zatim podporu pro snippety, která se v 0.9 bude měnit.

Nilp
Člen | 65
+
0
-

Já právě prezentační logiku controlů řeším „push“ stylem: v šabloně presenteru mám něco jako {$cart->renderSummary('@Cart.summary.phtml')} – znovupoužitelná komponenta prostě předá nějaká data „mojí“ šabloně, a ta je vykreslí. Šablona tak vlastně vůbec controlu nepatří a o nastavení se stará presenter.

Nenapadají mě zrovna žádné nevýhody, ale Nette používám spíš krátce, zajímalo by mě co na to řekne někdo zkušenější.

Editoval Nilp (11. 5. 2009 21:11)