problém s routováním – začátečník

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

Ahoj, potřeboval bych poradit s nastavením routování.

chci abych měl adresy jednoduchého webu:

homepage vytváří presenter HomepagePresenter, page pak PagePresenter, šablony mám Homepage.default, Page.default

router mám nastavený takto:

$router[] = new Route('<presenter>/<action>/<id>', array(
    'presenter' => 'Homepage',
    'action' => 'default',
    'id' => NULL,
));

v PagePresenter mám toto: (vytváří menu + požadovaný článek v $nodeID

public function renderDefault($nodeID)
{
	$this->template->menu = $this->model->getMenu();
	$this->template->node = $this->model->getNode($nodeID);
}

odkaz vytvářím takto:

<li><a href="{link Page:default, $row['id']}">{$row['title']}</a></li>

problém je že mě to odkaz vytvoří ve tvaru:
www.neco.cz/page/?…, nevím jak a co změnit abych měl tvar www.neco.cz/page/2

díky za radu

Ondřej Mirtes
Člen | 1536
+
0
-

Musí ti souhlasit název parametru v routě a v metodě render presenteru, takže:

public function renderDefault($id)
{
        $this->template->menu = $this->model->getMenu();
        $this->template->node = $this->model->getNode($id);
}
Patrik Votoček
Člen | 2221
+
0
-

V první řadě

<li><a href="{plink Page:default 'id'=>$row['id']}">{$row['title']}</a></li>

Předával jsi parametr ale né jeho název… :-) Nicméně stejně ti to bude generovat adresu www.example.com/page/default/1 … Protože nemáš nastaven router tak jak požaduješ musle by jsi tam mít navíc nebo místo té co tam máš teď tuto routu:

$router[] = new Route('page/<id>', array(
    'presenter' => 'Page',
    'action' => 'default',
    'id' => NULL,
));

Editoval vrtak-cz (13. 10. 2009 10:09)

vlki
Člen | 218
+
0
-

vrtak-cz napsal(a):

V první řadě

<li><a href="{plink Page:default 'id'=>$row['id']}">{$row['title']}</a></li>

Ten název tam být nemusí. Zjistí se z metody renderDefault.

Nová routa a LastHunterova oprava by to měly vyřešit.

Jan Jakeš
Člen | 177
+
0
-

Toto lze už vyřešit (včetně zachování action na svém místě) jedinou routou:

$router[] = new Route('<presenter>/{<action>/}<id>', array(
    'presenter' => 'Homepage',
    'action' => 'default',
    'id' => NULL,
));
Patrik Votoček
Člen | 2221
+
0
-

Juan napsal(a):

Obávám se že takhle to nepůjde… protože nemůžeš mít nepovinný parametr před povinným… jak i kdyby jsi dal ID jako nepoviné tak to stejně nebude ono a stejně ti to tam tu action bude házet. Protože jak jinak by nette rozeznalo jestli www.example.com/page/10 je presenter page a action 10 nebo jestli to je presenter page a action default s parametrem id hodnoty 10…

Editoval vrtak-cz (13. 10. 2009 12:04)

Ola
Člen | 385
+
0
-

Ty složený závorky udělaj to kouzlo :-) → Pokud je adresa page/default/1 tak Nette přesměruje na page/1, pokud je adresa page/edit/1 tak jí to nechá :)

Editoval Ola (13. 10. 2009 12:28)

mklapal
Člen | 4
+
0
-

díky za všechny připomínky a rady, konečně jsem se začal v těch routách trochu orientovat. Ještě mám jeden dotaz, kdybych chtěl aby adresa stránky byla např.:

www.neco.cz/uvod nebo www.neco.cz/…tni-formular, tak místo ID budu předávat název stránky, v routeru bude:

$router[] = new Route('<title>', array(
    'presenter' => 'Page',
    'action' => 'default',
    'id' => NULL,
));

akorát nevím jak zajistím aby se zobrazila stránka s názvem kontaktní formulář (s háčky, čárkami, mezerami) když v adrese bude /kontaktni-formular? nebo musím za název přidat ID a podle toho to identifikovat (např. /kontaktni-formular-1?

Patrik Votoček
Člen | 2221
+
0
-

Ola napsal(a):

Ty složený závorky udělaj to kouzlo :-) → Pokud je adresa page/default/1 tak Nette přesměruje na page/1, pokud je adresa page/edit/1 tak jí to nechá :)

Tím si nejsem zase tak jistej… (dost silně o tom pochybuju) :-/ protože jak pak nette pozná že 1 není název action ale id (myslím u page/1)

mklapal napsal(a):

Jsem tohle něják zapoměl zkopírovat… :-/ Takže nejjednodušeji si udělej nějákou tabulku kde bude „nevic-zlutoucky-kun“ ⇒ „Nejvíc žluťoučký kůň“

Editoval vrtak-cz (13. 10. 2009 13:32)

Ola
Člen | 385
+
0
-

Já si tim jistej sem protože jsem to i zkoušel :) Zkus kouknout sem: https://forum.nette.org/…lne-sekvence

David Grudl
Nette Core | 8099
+
0
-

vrtak-cz napsal(a):

Obávám se že takhle to nepůjde… protože nemůžeš mít nepovinný parametr před povinným…

Dnes už to jde, právě díky složeným závorkám. Nicméně klasickou cestou (tj. bez složených závorek a s výchozími hodnotami) to možné není.

Protože jak jinak by nette rozeznalo jestli www.example.com/page/10 je presenter page a action 10 nebo jestli to je presenter page a action default s parametrem id hodnoty 10…

Rozezná to podle regulárních výrazů – které v tomto případě asi ani není potřeba uvádět, protože výchozí pattern pro presenter a action je [a-z][a-z0-9.-]*, tedy samotné číslo neprojde.

Jan Jakeš
Člen | 177
+
0
-

Proč si to radši nevyzkoušíte a tvrdíte, že to nejde, když to jde?

Pokud chcete lépe rozlišovat ID a action, dá se tomu pomoct regulárními výrazy. Fantazii tady opravdu nic nebrání… Například v následujícím příkladu přesně specifikuji tvar jazyka – bere tvar cs nebo třeba en-us. Například en-usx už by bylo bráno jako presenter.

'{<lang [a-z]{2}(?:-[a-z]{2})?>/}<presenter>?action=<action>'

Navíc mohu zadat i jména presenterů (nebo action atd.), která routa bude brát:

<presenter homepage|auth|test>

EDIT: David mě předběhl. Každopádně snad můj příspěvek alespoň demonstruje, že regulární výrazy lze rozšířit…

Editoval Juan (13. 10. 2009 13:26)

Patrik Votoček
Člen | 2221
+
0
-

David Grudl napsal(a):

Dnes už to jde, právě díky složeným závorkám. Nicméně klasickou cestou (tj. bez složených závorek a s výchozími hodnotami) to možné není.

Tak to se omlouvám za dezinformaci… :-(

Rozezná to podle regulárních výrazů – které v tomto případě asi ani není potřeba uvádět, protože výchozí pattern pro presenter a action je [a-z][a-z0-9.-]*, tedy samotné číslo neprojde.

To jsem si říkal taky… Ale že je to až tak vymakané mě nedocvaklo… :-) ale jak se to zachová v případě kdy ono číslo nahradíme třeba slug-em? (třeba „neco-neco“)?

Editoval vrtak-cz (13. 10. 2009 13:36)

Ola
Člen | 385
+
0
-

Pak to v případě, že neexistuje action neco-neco vyhodí BadRequestException (No route for Presenter:neco-neco)

Jan Jakeš
Člen | 177
+
0
-

To jsem si říkal taky… Ale že je to až tak vymakané mě nedocvaklo… :-) ale jak se to zachová v případě kdy ono číslo nahradíme třeba slug-em? (třeba „neco-neco“)?

Pokud máš třeba {<action>/}<id> (a ID je nepovinné) a zadáš neco-neco, bude to action. Bere se to asi zleva na první pattern, který na to pasuje.

Pokud ale používáš nějaké filtry (například na ID) a filtr vrátí NULL, pak routa také vrátí NULL a použije se další routa v pořadí. A v tom je velká síla routování – neexistující stránky lze nechat „proplout“ například k routě, která tě nasměruje na presenter, který nabídne její vytvoření (podobně jako na nette.org), atd.

Na univerzální cool-url, kde se v URL nevyskytuje ani presenter (je tam jen třeba nadpis-clanku nebo kontakt) je potřeba buď použít více filtrů (nepříliš dobré řešení) nebo napsat vlastní router, kerý se opírá například o databázi. Tady se případným kolizím názvů těžko vyhneš a musíš si stanovit, co má vyšší prioritu. Například můj vlastní router napřed hledá řetězec ID v databázi → pokud nenajde, vrátí NULL → použije se další routa, která řetězec interpretuje jinak nebo nabídne vytvoření stránky, atd…

Patrik Votoček
Člen | 2221
+
0
-

Ola napsal(a):

BadRequestException (No route for Presenter:neco-neco)

Spíš Presenter:necoNeco :-)

Juan napsal(a):

Bere se to asi zleva na první pattern, který na to pasuje.

Tohle stacilo zbytek vím ale pro nekoho kdo nevi se to bude hodit… :-)

Ola
Člen | 385
+
0
-

Jo, a hlavně to tu hlášku co jsem psal nevyhodí :) Trošku jsem to popletl, vyhodí to hlášku o neexistující šabloně.

Jan Jakeš
Člen | 177
+
0
-

Tohle stacilo zbytek vím ale pro nekoho kdo nevi se to bude hodit… :-)

Heh, no neva, třeba to někomu pomůže :) Snad bych jen doplnil, že pokud máš masku {<action>/}<id> a parametr ID je povinný, třída Route je tak chytrá, že samotný řetězec neco-neco bude ID.

David Grudl
Nette Core | 8099
+
0
-

David Grudl napsal(a):

vrtak-cz napsal(a):

Obávám se že takhle to nepůjde… protože nemůžeš mít nepovinný parametr před povinným…

Dnes už to jde, právě díky složeným závorkám. Nicméně klasickou cestou (tj. bez složených závorek a s výchozími hodnotami) to možné není.

Tak v poslední revizi už je povolený i volitelný parametr nalevo od povinného.