Rozšiřování funkcí presenteru – komunikace více presenterů mezi sebou?
- nanuqcz
- Člen | 822
Ahoj, pořád se učím v Nette (pomalu, času není moc), a udělal jsem si jednoduché CMS na správu článků. Teďka chci mít možnost ke článkům přidávat fotogalerie. Administrace je mi jasná, ale co frontend část?
Abyste chápali v čem mám problém – napadlo mě řešit to několika způsoby:
- Rozšířit metodu renderView v ArticlePresenteru, jednoduše do něho připsat kód, který do templatu kromě článku vloží i data fotogalerie. Co ale, až budu chtít v budoucnu přidat ke článkům taky diskuzi, anketu apod.? Budu mít v ArticlePresenteru plno kódu, který se vlastně netýká článků.
- Vytvořit si komponentu, která bude tahat z DB galerii a pouze ji zavolám v šabloně:
<h2>{$title}</h2>
<p>{!$content}</p>
{widget gallery $id}
To bych ale zase v ArticlePresenteru musel vytvářet metodu createComponentGallery a v budoucnu i createComponentForum, createComponentPoll, … a jsme u stejného problému.
- Nějak zařídit, aby se při požadavku na zobrazení článku zavolal ArticlePresenter:view, vložil do šablony článek, pak aby se zavolal GalleryPresenter:view, vložil do šablony galerii a pak až se šablona vykreslila. To ale nemám páru, jestli to vůbec jde (předpokládám že ne)
- Nastavit ArticlePresenter, aby dědil z GalleryPresenteru, který už mu do šablony naháže informace o galerii, a ArticlePresenter tam pak už jen přidá článek. A pak v případě, že tam budu chtít přidat i hlasování a diskuzi, tak z hlasování bude dědit diskuze, z diskuze bude dědit galerie a z galerie bude dědit presenter pro články? (všechny budou k šabloné přistupovat asi v metodě renderView)
Díky za tipy a rady, od rána si nad tím lámu hlavu :-)
- tomolas
- Člen | 66
No ja by som to riesil proste tak, ze by som do presenteru jednoducho pridal 1 volanie modelu. Nieco ako
<?php
public function renderArticle($article_id){
$article_model = new Article();
$gallery_model = new Gallery();
$this->template->article_data = $article_model->getArticle($article_id);
$this->template->gallery_data = $gallery_model->getGallery($article_id);
}
?>
Galeriu v sablone zvladnes jednym {foreach}. A smitec! Je to odpoved na to co si sa pytal?
- OK3
- Člen | 91
Metody na vytváření komponent (diskuse, galerie apod.) si můžeš umístit do BasePresenteru, od kterého dědí ostatní presentery. Kód šablony – vykreslení komponent – pak volá tyto metody. Tak se ti nebude hromadit ani duplikovat kód v ostatních presenterch. Ber to jako poznámku k druhé části tvého navrhovaného řešení..
- Filip Procházka
- Moderator | 4668
https://doc.nette.org/…/smartobject#… tady máš Extesion metody, co se týče továrniček navrhoval bych trošku odlišné řešení
class BasePresenter extends \Nette\Application\Presenter
{
// ...
/*=========================== Standalone Forms initialization =============================*/
public function createComponent($name)
{
// prvně se kouknu jestli nemám továrničku přímo v presenteru
$component = parent::createComponent($name);
if ($component !== Null) {
return $component;
}
// asi ne tak zkusím jestli to nesmrdí formulářem
if ($m = String::match($name, "~^(?P<form>.+)Form$~")) {
$ns = $this->reflection->getNamespaceName();
// kouknu jestli náhodou nejsem v modulu, abych mohl prvně šahat po formulářích, které jsou blíž
if (String::match($ns, "~^[^\\\\]+Module$~")) {
$formClass = $ns . "\\Form\\" . ucfirst($m['form']);
if (class_exists($formClass)) {
return $component = new $formClass($this, $name);
}
}
// asi žádné takové nemám, tak zkusím ještě globální
$formClass = "\\Kdyby\\Form\\" . ucfirst($m['form']);
if (class_exists($formClass)) {
return $component = new $formClass($this, $name);
}
}
}
/*=========================== Common Components =============================*/
public function createComponentNavigation($name)
{
return $navigation = new Kdyby\Addons\Navigation($this, $name);
}
}
Snad je to pochopitelné, pokud máš fomulář v samostatné třídě s namespace ve tvaru
FrontModule\ForumModule\Form\Contact - největší priorita
FrontModule\Form\Contact - menší priorita
Kdyby\Form\Contact - nejmenší priorita
Tak ho to načte a vrátí jako komponentu, jenom ještě musím doladit
navěšování handlerů :)
Koncept se dá samozřejmě použít i na další komponenty a můžeš si tak
vytvořit konvenci pro dynamické vytváření komponent.
Je to HODNĚ magické, ale funguje to perfektně a podle
očekávání :)