Generovanie URL z routra
- srigi
- Nette Blogger | 558
Nekcem byt za zleho a toho co rype, ale tento FW fakt nema fnci na generovanie URL z routra? Teda akoze prepripravenu a dostupnu ako napr. VIEW a (aj) PRESENTER helper. Toto maju vsetky dolezite frameworky (Zend, Symfony). Viem, ze je tu nejaka metoda link, ale to mi je na nic, ked potrebujem generovat konkretnu URL, ktora zasiahne konkretnu routu. Konkretne – mam routu:
<?php
$router[] = new Route('<lang [a-z]{2}>/<url>', array( // teda napr. www.example.com/sk/lorem-ipsum-dolor
'module' => 'Front',
'presenter' => 'Page',
'action' => 'default'
));
?>
No a ja potrebujem vygenerovat URL na rovnaku routu, napr. pre iny parameter
<url>. Da sa to vobec v Nette?
THX.
- Ondřej Mirtes
- Člen | 1536
Samozrejme, to je jedna ze zakladnich funkci frameworku.
V Presenteru metodou link:
$this->link('Page:', array('url' => 'nejaka-url'));
V sablone:
{link Page: nejaka-url}
Editoval Ondřej Mirtes (18. 1. 2010 16:44)
- srigi
- Nette Blogger | 558
Lenze toto „zprzni“ vygenerovanu URL na
/page/?url=nejaka-url
, cize na jej generovanie sa pouzije (asi,
neviem ako to funguje) ta defaultna routa. Napr. v Symfony existuje takato vec
(je umoznena tym, ze Symfony ma pomenovane routy, Zend to tusim tiez umoznuje,
z rovnakeho dovodu):
<?php
url_for('@page_by_url?lang=' . $lang . '&url=' . $page->getUrl($lang)));
?>
definicia routy (yaml):
<?php
// oddelovace php pls ignorujte
page_by_url:
url: /:lang/:url
param: { module:page, action:byurl } # module je nieco ako Presenter/Controller (pozor, nie je to modul!)
?>
Cize aj keby na rovnaku akciu existovala URL
napr. www.example.com/page/byurl/sk/blablabla
tak, url_for()
na zaklade pomenovanej routy vygeneruje
www.example.com/sk/blablabla
A toto by som potreboval.
- srigi
- Nette Blogger | 558
Funkcionalitu som nakoniec pokusne nakodil pomocou rozsirenia BasePresenter:
<?php
namespace FrontModule;
class BasePresenter extends \BasePresenter
{
public function url($params)
{
$router = \Nette\Environment::getApplication()->getRouter();
$request = clone $this->getRequest();
$request->setParams($params);
return $router->constructUrl($request, \Nette\Environment::getHttpRequest());
}
}
?>
Ked funkcii poslem pole
array('lang'=>'en', 'url'=>'nejaka-pokusna-url', 'param'=>'blabla', 'param2'=>'estejeden')
tak router parametre „prežuje“ a vyhodi
url:http://www.example.com/en/nejaka-pokusna-url?param=blabla¶m2=estejeden
Ked routu z prveho prispevku vyhodim z aplikacie, tak URL
je http://www.example.com/?lang=en&url=nejaka-pokusna-url¶m=blabla¶m2=estejeden
Dufam, ze je vidiet ten rozdiel a o com mi ide. Len by ma zaujimalo, ci je toto v Nette nativne.
Editoval srigi (18. 1. 2010 17:33)
- Ondřej Mirtes
- Člen | 1536
Nic takového není třeba, Nette má podporu pro hezké URL implementovánu nativně. Ukaž nám definici všech tvých rout – záleží u nich na pořadí, v jakém jsou uvedeny.
- Jan Tvrdík
- Nette guru | 2595
srigi napsal(a):
Viem, ze je tu nejaka metoda link, ale to mi je na nic, ked potrebujem generovat konkretnu URL, ktora zasiahne konkretnu routu.
Nette je v tomto ohledu dál, než ostatní FW. Špičková práce s URL je jednou z jeho klíčových vlastností. Akorát musíš správně napsat (a seřadit) routy :)
Zkus si přečíst v dokumentaci něco o Routování
- David Grudl
- Nette Core | 8218
srigi napsal(a):
je umoznena tym, ze Symfony ma pomenovane routy, Zend to tusim tiez umoznuje, z rovnakeho dovodu
Nette nemá pojmenované routy, protože je nepotřebuje, ale je pravda, že pro programátory přicházející z jiných frameworků to může být překvapivé. Takže doporučuji nejprve mrknout na ten manuál.
- srigi
- Nette Blogger | 558
No ja studujem vsetko okolo Nette posledne dva tyzdne. Zistil som, ze ten
spravny tvar URL dostanem, ked prehadzem routy od najzlozitejsej po
najjednoduchsiu. Ale kcem sa ta David spytat – ked do fnci ako je napr.
$presenter->link()
, alebo redirect()
nasypem
parametre, vysledna URL je ziskavana reverzne z rout? Vid koniec mojho
posledneho postu.
Editoval srigi (19. 1. 2010 0:22)
- Ondřej Mirtes
- Člen | 1536
ten spravny tvar URL dostanem, ked prehadzem routy od najzlozitejsej po najjednoduchsiu
To je účel :)
Routy jsou implementované tak, že každá má metodu match()
(pro směr HTTP požadavek → zavolání Presenteru) a
constructUrl
(z odkazu na metodu Presenteru vytvoří URL), díky
tomu, že implemetuje rozhraní IRouter.
Při zadání URL do prohlížeče se spustí Nette aplikace a začne projíždět jednotlivé routy, v pořadí, v jakém jsou uvedeny. Na každou routu padne rozhodnutí, zda-li vrátí NULL (čímž dá routeru vědět, že URL pro ní nepatří a má postoupit k další routě) anebo vrátí PresenterRequest objekt (čímž přeruší řetěz a už se nemusí kontrolovat další routy), ze kterého se spustí daný Presenter a jeho určené metody.
Při požadavku na vytvoření odkazu nastává analogická situace – opět se projíždějí jednotlivé routy, ty, které mají příznak Route::ONE_WAY, jsou automaticky přeskakovány (jsou jednosměrné – nelze na ně vytvořit odkaz, ale požadavek přijímají), a zbylé se opět vyhodnocují, zda-li jsou pro daný PresenterRequest nejvhodnější.
- David Grudl
- Nette Core | 8218
Ano, URL se získává reverzně z rout.
Doporučuju nastartovat Routing Debugger (v adresáři tools) a vyzkoušet si vizuálně, jak to funguje. V podstatě jde o síto, routy se uvádějí od nejspecifičtějších po nejobecnější.