Banalita – default action
- Aearsis
- Člen | 57
Zdravím,
ve verzi 0.9 bylo možné definovat default akci presenteru přes statickou $defaultAction. Ve 2.0 se z toho udělala konstanta, a nikde na fóru jsem nenašel důvod…
Nešlo by v Presenter::createRequest()
a
::initGlobalParams()
zaměnit self::DEFAULT_ACTION
za
static::DEFAULT_ACTION
, aby se to dalo alespoň nějak změnit?
Díky
- Mikulas Dite
- Člen | 756
default
je kouzelná v tom, že se nikam psát nemusí. Objeví
se leda v názvu souboru a nějaké metody, ale odkazování je jenom
Modul:Presenter:
a ne Modul:Presenter:default
.
Když je to konstanta, nestačí ji změnit v BasePresenteru?
Edit: je tam self
, takže nešlo. Škoda.
Editoval Mikulas Dite (22. 5. 2011 23:00)
- Ondřej Mirtes
- Člen | 1536
Já si myslím, že to David omezil schválně. Mít napříč projektem
různé významy pro zápis {link Presenter:}
by bylo matoucí.
- Aearsis
- Člen | 57
To jo, ale takto to nejde udělat ani v BasePresenteru, takže mi Nette určuje že to bude vždycky default, a nejde to změnit (pokud nechci zkopírovat tyhle dvě metody do BasePresenteru) – a to je přesně to co Nette dělat nechce ne? :)
@Mikulas: a objeví se taky v url, což je to co mi vadí…
Editoval Aearsis (22. 5. 2011 23:22)
- Ondřej Mirtes
- Člen | 1536
Proč bys to chtěl předefinovat globálně? Proč ti jiný název, než default, přijde lepší?
22: S routami to nesouvisí, to by tam ta konstanta nebyla potřeba vůbec :)
- _Martin_
- Generous Backer | 679
@22: To ne, potom by nebylo možné rozeznat ID od jména akce.
@Aearsis: Defaultní akce je od toho, že se nemusí uvádět. Pokud plánuješ nějakou akci zobrazovat v 99% adres, pravděpodobně by to neměla být ta defaultní.
Z toho důvodu se s adresou /presenter/default/id
prakticky
nesetkáš – nedávalo by to smysl.
Editoval _Martin_ (23. 5. 2011 0:16)
- _Martin_
- Generous Backer | 679
@Aearsis: Potom je to otázka nastavení routy, vzhledem k tomu, že jde o akci s parametrem. Tedy něco takového:
$router[] = new Route('<presenter>/<action>/<id=0>', 'Page:show');
Zkus ještě zvážit ten tvar adres /page/show/page-name
–
/page/show
neodráží logickou strukturu, ale spíš technickou
implementaci webu.
- _Martin_
- Generous Backer | 679
@Aearsis: Můžeš nějak víc popsat tu appku? Jako
presentery, akce a jejich parametry. Možná by to chtělo jinou strukturu
aplikace a nebo vlastní routy – nedokážu soudit z jednoho příkladu, ale
„potřeba změny defaultAction
+ její použití s parametrem +
ve všech presenterech“ na mě působí nezvykle.
- Aearsis
- Člen | 57
Není to nic netradičního, ale v zásadě bych to chtěl na presentery Page, File, Article a Gallery. Všechny mají svou výchozí fci něco zobrazit, všechny (až na File) mají co zobrazit i bez parametru.
Uznávám, že tohle se dá vyřešit i jednoduše, v default
provést show,0
. Ale muselo by se to všude explicitně napsat.
- _Martin_
- Generous Backer | 679
@Aearsis: Nějak se v tom ztrácím: zkus mi polopaticky vysvětlit, proč potřebuješ měnit
defaultAction
.
Mate mě následující:
Prostě se mi nelíbí /page/default/contact když můžu mít /page/show/contact, stejně jako /product/show/neco atp…
vs. následné:
$router[] = new Route('page/<id=0>', 'Page:show');
Dle routy akci v adresách nezobrazuješ.
P.S. Navíc na mě id=0
působí dojmem, že přenášíš
routování do akce presenteru, namísto využití routeru.
- Ondřej Mirtes
- Člen | 1536
To, co řešíš, je nesmysl, máš špatně napsané routy a s konstantou v presenteru to nijak nesouvisí.
V presenteru Page
měj akci renderDefault()
,
která ti vypíše seznam položek a renderShow($id)
, která ti
vypíše jednu konkrétní položku.
Tyhle dvě routy ti pak obstarají ideální URL:
$router[] = new Route('page', array(
'presenter' => 'Page',
'action' => 'default',
));
$router[] = new Route('page/<id>', array(
'presenter' => 'Page',
'action' => 'show',
));
Pokud bys to chtěl zobecnit s tím, že máš víc presenterů, které mají stejné default a show akce + nějaké další jiné, tak takto:
$router[] = new Route('<presenter>/<action redakce|archiv|kompletni|xml|kratke-zpravy|komentare>', array(
'action' => 'default',
));
$router[] = new Route('<presenter>/<id>', array(
'action' => 'show',
));
- Aearsis
- Člen | 57
@Ondrej Mirtes: Já ale chci, aby Page/default zobrazilo homepage, ne seznam článků. A místo druhého řešení mi fakt přijde
const DEFAULT_ACTION = "show";
lepší, a navíc nemusím kvůli každému novíému presenteru s touto vlastností měnit bootstrap (nebo routy někde jinde). (A taky mi /page/komentare nevrátí homepage, což by tímhle řešením udělalo)
@Martin: tahle routa samozřejmě může být
$router[] = new Route('<presenter page|file|gallery|article>/<id=0>', array("action" => "show"));
a bude to vyřešeno. Chtěl jsem, aby presentery měli jako default
akci:
Page – zobraz homepage dle databáze,
Gallery – zobraz domovskou stránku
Article – zobraz nejnovější článek
a pokud by existoval parametr, tak by zobrazila rovnou tu stránku, článek,
složku.
Uznávám tedy, že můj požadavek lze vyřešit lépe než změnou default akce. Na druhou stranu si myslím, že by mělo být programátorovi umožněno default akci si změnit, už proto že takhle mi framework „diktuje“ co mám používat. A také bych rád slyšel vyjádření Davida, proč to zakázal – třeba pro to má svůj dobrý důvod.
Edit: teď jsem si uvědomil, že když použiju default a v ní
changeAction("show")
, tak mi to z www.example.com/
udělá www.example.com/page/show
. Existuje nějaké řešení,
při kterém bude Page:default
vykreslovat to samé co
Page:show,0
, aniž by se změnila url?
Editoval Aearsis (23. 5. 2011 16:17)
- Patrik Votoček
- Člen | 2221
Budto jsem totalne mimo nebo fakt nevim ale vubec nechapu wo co go!
Můžeš pls uvés příklad tak 5ti adres na jake akce(+presentery) a parametry je chces?
- Ondřej Mirtes
- Člen | 1536
Taky jsem se v těch požadavcích už ztratil.
Konstanda DEFAULT_ACTION ovlivňuje pouze, jakou akci představuje zápis
{link Presenter:}
– nyní ve frameworku je to zkratka pro
{link Presenter:default}
.
Cokoli s URL se řeší pomocí rout.
- Aearsis
- Člen | 57
Ok, zkusím to polopaticky :)
Chci, aby:
:Page: == :Page:show,null
:Page:show,5 == :Page:show,5
:Gallery: == :Gallery:show,null
:Gallery:show,slozka/ == :Gallery:show,slozka/
Prostě bych rád, abych nemusel definovat akci default, která vykoná fci
stejnou jako show, akorát bez parametru. Buď musím načtení a zobrazení
stránky přesunout do jiné funkce a volat ji z obou, nebo přes
changeAction
, to ale změní url v prohlížeči, nebo zajistit
aby se nikde neodkazovalo na :Page: a dopsat všude :Page:show. Tohle všechno
za mě udělá změna dvou self na static za cenu nulového BC breaku,
nepatrného zpomalení (static je u mě cca o 5 ns pomalejší), nette už
nebude přikazovat že default akce je vždycky default, a určitě by se
ještě nějaké pro našlo.
Editoval Aearsis (23. 5. 2011 18:33)
- Aearsis
- Člen | 57
if ($id == null) {
$this->template->page = \Model\Page::find(array("id" => \Model\Setting::find("Homepage id")));
if ($this->template->page == null)
throw new \Nette\Application\BadRequestException("Domovská stránka nenalezena! Špatné nastavení!", 404);
} else {
$this->template->page = \Model\Page::find(array("id" => $id));
if ($this->template->page == null)
throw new \Nette\Application\BadRequestException("Stránka nenalezena", 404);
}
... kontrola oprávnění, breadcrumbs, titulek atp. ...
Editoval Aearsis (23. 5. 2011 18:36)
- bazo
- Člen | 620
presun tento kod
<?php
$this->template->page = \Model\Page::find(array("id" => \Model\Setting::find("Homepage id")));
if ($this->template->page == null)
throw new \Nette\Application\BadRequestException("Domovská stránka nenalezena! Špatné nastavení!", 404);
?>
to actionDefault() mas to, co si chcel. a este sa zbavis aj ifu
- bazo
- Člen | 620
tak na to si sprav bud komponentu alebo to presun do beforeRender(), alebo to
vyclen do samostatnej funkcie a tu zavolas na konci
edit: page predavas do template, titulok a ostatne veci z page nastavuj teda
v sablone, na breadcrumbs komponentu a je to
Editoval bazo (23. 5. 2011 19:10)
- _Martin_
- Generous Backer | 679
Některé části kódu můžeš dát do společných metod, viz. životní cyklus presenteru.
- Ondřej Mirtes
- Člen | 1536
Přesně, jak jsem si myslel – metoda a v ní dvě velké větve
if
a else
. Přesně kandidát na rozdělení do
renderDefault
a renderShow
;)
Ten společný kód, tedy breadcrumbs apod. můžeš přesunout do
beforeRender()
nebo afterRender()
.