Autor Zpráva
Tori
Profil
Trochu jsem si upravila router (od Jakuba Kulhana), přidala další možnosti. Je použitelný pro objektovou aplikaci (kontroler+metoda) i pro web skládaný pomocí include $_GET['page'].'.php'; (odvozená třída RouterForIncludes). Nechci sem lepit kilometr kódu, je ke stažení pod uvedeným odkazem, hned nahoře.
Jak se vám to jeví, jak třída/-y tak dokumentace? Co byste napsali jinak? V případě kódu mám rozdělanou další verzi, kde budou lépe oddělené objekty Router, Route, Request atd., aby to nebyla taková jedna všehoschopná obluda. Díky moc za názory i rady.

http://projekty.vize.name/router/

edit: Obě třídy jsou i na pastebinu, ať nemusíte stahovat .zip: Router, RouterForIncludes.
Lamicz
Profil
Tori:
O víkendu vyzkouším, něco takového hledám ;). BTW mám "něco mezi" - OOP třídy (kontrolery) s autoloadem řízeným old school $_GET['page'] :) Holt zatím nebyl čas toto řešit a CMS vznikalo v době kdy ještě nebývaly na levných a free hostinzích povoleny .htaccess...
Tori
Profil
Kdyby se přeci jen někomu chtělo se na kód routeru podívat a zhodnotit ho, byla bych moc ráda.
Omlouvám se moderátorům za nakopávání vlákna.
Ugo
Profil
to sem zvědav jestli to někdo přelouská, každopádně já přestal i v apině číst po komentáři "Rozebere URL na parametry podle první vyhovující routy a vrátí výsledek" a jako u všech routingů co jsem kdy kritizoval (hlavně ten v nette) se ptám, co když druhá vyhovující routa vyhovuje lépe? V nette je to problém který jsem nemohl překousnout i přesto že zbytek routování je tam výbornej. Takže co bych přidal já (třeba to tu je nějak řešené, ale probírat se takhle dlouhým kódem je utrpení) je něco jako bodovací systém, trochu vysvětlení se najde na připravované dokumentaci: http://luci-project.org/dokumentace/advancedrouter/ v univerzálním routeru to bude ale možná neřešitelné, jelikož těžko budeš poznávat zda soubor, controller, jeho metoda atp. existují když není jisté kde se berou. Nicméně je to krůček který většině routerů chybí i přesto že mají zas jiné výhody než to moje, třeba překlady (umí to překlady rout? :-) )
Tori
Profil
Ugo:
to sem zvědav jestli to někdo přelouská
Tož je to víceméně první dokumentace k něčemu, kterou jsem psala, takže srozumitelnost tomu odpovídá. Příště to třeba bude lepší. :)

co když druhá vyhovující routa vyhovuje lépe?
Označení "první", "druhá" se vztahuje k pořadí, v jakém byly definované, tzn. je potřeba je definovat od přesně zadaných k obecným. Příklad z vaší stránky by se u mne napsat takhle:

$router->addRoute('/:controller/:page<\d+>', array('action' => 'index')); // omezuje druhou část URL jen na čísla
// anebo přesně zadaný kontroler: $router->addRoute('/:controller<main>/:page<\d+>', array('action' => 'index'));
$router->addRoute('/:controller/:action')); // sem přijdou všechny URL, kde druhá část neobsahuje jen čísla
U Nette se ta "první vyhovující" routa najde úplně stejně. To bodování je zajímavý nápad, i když ho určitě nevyužiju. No ale asi bych mohla přidat na stránku nějakou zkoušečku, kde by si člověk zadal routy a URL a viděl, co to udělá, bez nutnosti stahování/spouštění celého skriptu.

umí to překlady rout?
Překlad rout na ... co? Nepochopila jsem.
Zatím router neumí to, abych si jako v Nette mohla vytvořit URL ze zadání "Main:index, page=>$id", ale musím použít array('controller'=>'main', 'action'=>'index', 'page'=>$id) Bylo by to (asi) snadné doplnit, jen nechci (=je mi to blbé vůči autorům) zas až tak velmi Nette kopírovat. Ale možná časem to doplním, je to určitě čitelnější zápis.

těžko budeš poznávat zda soubor, controller, jeho metoda atp. existují když není jisté kde se berou
Tomuhle nerozumím, můžete to trochu rozvést? Funkce class_exists může zároveň volat autoloader a jména kontrolerů by měla mít nějakou jednotnou podobu (třeba <název>Controller), tak odkud ta nejistota?

A děkuju za ochotu. :)
Ugo
Profil
s tím louskáním jsem myslel spíš zdroják :-) moje texty jsou jinak tak o 10 úrovní níže.
bohužel s těmi routami kde se bere první mám zkušenosti že né vždy to lze napsat za sebe a musí se dojít ke kompromisu/změně, ale zas je to rychlejší a může to být jasnější pro nově příchozího k projektu

překladami rout myslím jazyky.. produkty->products atp. bez nutnosti definovat další routy, ale jen překlady, to se mi na právě třeba na nette opravdu líbí (přestože nette nepoužívám)

ta kontrola controlleru atp. je asi opravdu neřešitelná, myslím že když se dělá universální router, tak nesmí zavádět do projektu konvence, jinak by ztratil universálnost a tak není možné zjistit jestli si programátor pod controllerem "produkt" nepředstavuje třídu "letadlo", to je problém s tím napsat něco universálně, buď to funguje napůl nebo to dává konvence a nebo to má miliony nastavení a parametrů :)
Tori
Profil
Ugo:
překladami rout myslím jazyky
A jo tohle, tak to určitě neumí. Zájemce odkážu na Nette. :)

není možné zjistit jestli si programátor pod controllerem "produkt" nepředstavuje třídu "letadlo"
To by šlo obejít tím, že se kontroler nebude brát z URL, ale jako výchozí parametr:
$router->addRoute('/:produkt<produkt>/:?action', array('controller' => 'letadlo'));
Akorát teda pro vytvoření URL podle téhle routy by se muselo zadat oboje:
$router->url(array('produkt' => 'produkt', 'action' => 'index', 'controller' => 'letadlo')); # složí:  /produkt/index
Str4wberry
Profil
Lze tímto skriptem, Tori, vytvořit cesty pro adresy podobné adresám na této diskusi? Co si pamatuji, když jsem to kdysi zkoušel v Nette, tak to připomínalo spíš hackování.
Tori
Profil
Str4wberry:
Myslíte složené z parametrů+hodnot? To mě, přiznám se, ještě nenapadlo. Vyzkouším.
Tori
Profil
Str4wberry:
Zdá se, že ano: http://projekty.vize.name/router/test-jpw

Zápis cest je nešikovný, protože router neumí rozpoznat nepovinný kus URL (parametr+hodnota), ale jen nepovinnou hodnotu, od toho ta redundance. Router taky očekává, že musí být (buď v cestě nebo jako výchozí parametr) zadaný controller a action. Dá se to obejít nastavením výchozího kontroleru a/nebo akce pro celý router (konstruktor), při skládání URL z parametrů se nemusejí zadávat. Nevím, jestli tuhle závislost z routeru nevyhodím - spíš umožním její vypnutí -, je to trochu nešikovné.
Tori
Profil
Ugo:
když se dělá universální router, tak nesmí zavádět do projektu konvence
To máte pravdu. Co kdyby se teda mohla zadávat maska pro název třídy/metody/funkce, které se mají zavolat? S tím, že části v ostrých závorkách by byly názvy parametrů z URL. Připadá vám to intuitivní či ne? Zřejmě by to bylo nastavení pro celý router, i když v případě, že někdo nepoužívá žádné konvence, by se to mohlo možná hodit i pro jednotlivé routy.
rozebraná URL: controller=>main, action=>clanky, id=>5
"<controller>Controller:<action>" -- zavolá MainController->clanky()
"<controller>:action<action>,<controller>:render<action>" -- zavolá Main->actionClanky() a pak Main->renderClanky()
"<action>" -- zavolá funkci clanky()
A pro includované soubory by to bylo třeba:
rozebraná URL: include=>galerie, id=>1, lang=>cz
$router->setCallbackName(APP_ROOT.'/includes/<lang>/<include>.php');

↓ Ok, budu teda tykat. :)
Ugo
Profil
Tori:
To máte pravdu
já jsem já, nikoliv my :-)

tohle by určitě drtivé většině stačilo a přislo vhod, ze 2 řádků ukázky je to naprosto jasné takže intuitivní to asi je
Tori
Profil
Bude to fungovat přesně podle [#11]. Ještě by mne ale zajímal váš (= nejen Uga) názor: U Nette ty metody action<akce> nebo render<akce> nemusí být definované. Jelikož je tohle samostatný skript, co by bylo vhodnější: vyžadovat jen existenci tříd a samostatných funkcí, ale pokud nebude existovat metoda třídy, tak max. vyvolat E_NOTICE - anebo vyžadovat, aby existovaly všechny definované callbacky? Nebo aby ze zadaných callbacků existoval prostě alespoň jeden (kterýkoli)?
Totiž jeden extrém je, že vidím bílou stránku a nevím proč, druhý, že musím pro forma zbytečně definovat prázdné metody - takže hledám nějakou střední cestu.
Tori
Profil
Update, trochu jsem překopala kód a rozdělila na dvě třídy, snad bude (o něco málo) přehlednější.
Pastebin: Router + Route, a odvozená třída RouterForIncludes.

Callback/-y jsou libovolně nastavitelné, jak naznačeno v [#11], musí odkazovat na spustitelnou funkci/metodu (nepovinné metody si musí programátor řešit přes __call()). Tím pádem jediné povinné části routy jsou ty, které jsou použité v callbacku. Pro případné chyby se dá nastavit callback, který nepotřebuje žádné parametry z URL (např. ErrorController:index).
RouterForIncludes->delegate() includuje zadané skripty v omezeném kontextu, ale dají se jim poslat libovolné proměnné. I z includ.skriptu se dají poslat data do dalšího include.
Tori
Profil
Str4wberry:
Lze tímto skriptem, Tori, vytvořit cesty pro adresy podobné adresám na této diskusi?
Ad [#10]: Zjednodušila jsem zápis cest pro adresy podobné djpw: Další možnosti » adresy jen z parametrů Jak se vám to zdá, chybí něco podstatného?
Str4wberry
Profil
Hezké, to je přesně ono.

Vaše odpověď

Mohlo by se hodit

Odkud se sem odkazuje


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: