Banalita – default action

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

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
+
0
-

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
+
0
-

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
+
0
-

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)

22
Člen | 1478
+
0
-

moc nechápu, k čemu je to dobré, ale můžeš použít changeAction() v presenteru a nebo globálně si nastav routu z default action na nějakou jinou.

Ondřej Mirtes
Člen | 1536
+
0
-

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 :)

Aearsis
Člen | 57
+
0
-

Protože mi default přijde takový nicneříkající… Prostě se mi nelíbí /page/default/contact když můžu mít /page/show/contact, stejně jako /product/show/neco atp. – vetsinou je vychozi akce vetsiny presenteru neco zobrazit, nebo se pletu?

_Martin_
Generous Backer | 679
+
0
-

Bez urážky: /page/show/contact se ti líbí? A co bude na adrese /page/show, resp. /page? jsi si jistý, že zrovna defaultAction je to, co potřebuješ změnit?

Aearsis
Člen | 57
+
0
-

@_Martin_: homepage…

Jak to řešíte vy? Samozřejmě tohle všechno lze vyřešit jenom routama, případně alespoň na page speciální… Nenajde se tu někdo, komu se taky nelíbí /presenter/default/id :D ?

22
Člen | 1478
+
0
-

taková URL standardně nevznikne, protže defaultní akce se v URL vynechá, takže by ti to mělo hodit /presenter/id – pokud máš id

Aearsis
Člen | 57
+
0
-

To sem ještě neviděl… A co když id koliduje s názvem akce?

Edit: prosím pošli mi $mask routy co tohle udělá…

Editoval Aearsis (23. 5. 2011 0:13)

_Martin_
Generous Backer | 679
+
0
-

@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)

Aearsis
Člen | 57
+
0
-

A co když nemám něco jako homepage presenter, místo něj používám rovnou :Page:show,0? V tu chvíli nemá akce Page:default žádnou funkci, tím pádem default by měla být Page:show. Alespoň já si to myslím.

_Martin_
Generous Backer | 679
+
0
-

@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.

Aearsis
Člen | 57
+
0
-

@Martin: Samozřejmě že můžu použít (a pro Page zrovna použiju)

$router[] = new Route('page/<id=0>', 'Page:show');

ale mít to takhle pro všechny presentery je podle mě špatné.

_Martin_
Generous Backer | 679
+
0
-

@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
+
0
-

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.

hrach
Člen | 1834
+
0
-

Přijde mi to jako legitimní požadavek, ač autoro se tím snaží vyřešit něco jiného. Možná náhrada default může být třeba slovo index.

(Však si vzpomeňte, jak to bylo dříve, default.html ale index.html vyhrál :D :D)

Editoval hrach (23. 5. 2011 9:24)

_Martin_
Generous Backer | 679
+
0
-

@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
+
0
-

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
+
0
-

@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
+
0
-

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
+
0
-

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
+
0
-

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)

Ondřej Mirtes
Člen | 1536
+
0
-

Ukaž nám kód PagePresenter::renderShow() (případně actionShow()).

Aearsis
Člen | 57
+
0
-
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
+
0
-

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

Aearsis
Člen | 57
+
0
-

Ale spolu s tim budu muset znovu zkopírovat ten konec fce, kontrolu, nastavení titulku, breadcrumbs, zalogování zobrazení atd..

bazo
Člen | 620
+
0
-

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
+
0
-

Některé části kódu můžeš dát do společných metod, viz. životní cyklus presenteru.

Ondřej Mirtes
Člen | 1536
+
0
-

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

Aearsis
Člen | 57
+
0
-

O beforeRender jsem vědel, o afterRender ne. Děkuji, tím odpadají všechny námitky (kromě té že mi to nette přikazuje, ale s tím se smířím) :)