problém s routováním – začátečník
- mklapal
- Člen | 4
Ahoj, potřeboval bych poradit s nastavením routování.
chci abych měl adresy jednoduchého webu:
- www.neco.cz – homepage
- www.neco.cz/page/<id> – jednotlivé stránky webu, id je číslo stránky v databázi, takže např. www.neco.cz/page/1, www.neco.cz/page/8
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
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
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)
- Patrik Votoček
- Člen | 2221
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)
- mklapal
- Člen | 4
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
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
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 | 8228
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
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
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)
- Jan Jakeš
- Člen | 177
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
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… :-)
- David Grudl
- Nette Core | 8228
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.