Generovanie URL z routra

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

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

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

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

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&param2=estejeden

Ked routu z prveho prispevku vyhodim z aplikacie, tak URL je http://www.example.com/?lang=en&url=nejaka-pokusna-url&param=blabla&param2=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
+
0
-

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

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

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

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

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

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ší.