Routování – vícenásobná adresa předaná do argumentu
- Inferi
- Člen | 18
Ahoj,
chci se zeptat, jaký způsobem lze do argumentu/parametru zachytit více, než jeden název oddělený lomítkem. Jde o to, že se mi adresa skládá z adresy webu, jazyka a následně odkazy na články, který můžou být zároveň kategoriemi. Tzn. teoreticky libovolná hloubka. Je nějaký způsob, jak v routě zachytit parametr jakožto pole, nebo i jako řetězec pro následné rozparsování.
Př. www.example.cz/…/html/canvas
$route[] = new Route('<language>/<id>', 'Homepage:default', Route::SECURED);
Jde o to, aby v $id pak bylo „/programovani/web/html/canvas“.
Předem děkuji za jakoukoli radu,
Martin
- Filip Procházka
- Moderator | 4668
v ideálním případě by jsi si měl udělat různé routery, které budou filtrovat příchozí požadavky, podle jednotlivých argumentů. Ale tobě bude asi stačit i tohle:
$route[] = new Route('<language>/<id .?*>', array(
'presenter' => 'Homepage',
'action' => 'default',
'id' => array(
Route::FILTER_IN = function ($id) {
return explode('/', $id);
},
Route::FILTER_OUT = function ($path) {
return implode('/', $path);
},
)
), Route::SECURED);
při adrese /cs/programovani/web/html/canvas
class HomepagePresenter extends BasePresenter
{
public function renderDefault($id)
{
dump($id);
}
}
získáš výsledek 'programovani', 'web', 'html', 'canvas'
- Vyki
- Člen | 388
Já to dělám následovně. Z databáze si vezmu strom katalogu. Ten si seřadím, aplikuji na něj svoje filtry, ale to není podstatné. Podstatné je že dostanu pole.
<?php
$katalog = array(
1 => 'katalog/knihy/php/1001-triku-pro-php',
3 => 'katalog/knihy',
45 => 'katalog/knihy/php',
12 => 'katalog/test'
);
?>
Toto pole si uložím do cache – jednou bude klíčem id, podruhé bude klíčem kategorie.
<?php
$cache = Environment::getCache('Route.Katalog');
$cache->save('filterIn', $katalog, array(
Cache::TAGS => array('route#katalog')
));
$cache->save('filterOut', array_flip($katalog), array(
Cache::TAGS => array('route#katalog')
));
?>
O routování se starám následovně.
<?php
$cache = Environment::getCache('Route.Katalog');
Route::$styles['#katalog'] = array(
Route::PATTERN => '.*',
Route::FILTER_IN => function($s) use ($cache){
if(substr($s, -1) === '/') $s = substr($s, 0, -1);
$table = $cache['filterIn'];
if(isset($table[$s])) return $table[$s];
return NULL;
},
Route::FILTER_OUT => function($id) use ($cache){
$table = $cache['filterOut'];
if(isset($table[$id])) return $table[$id];
return NULL;
}
);
$router[] = new Route('<id #katalog>', array(
'presenter' => 'Katalog:Default',
'action' => 'default',
));
?>
Demonstruji na tom jak to mám udělané já, ale tento kód jsem netestoval. Ve svojí aplikaci to mám implementováno trochu komplikovaněji, tak snad to bude z tohoto jasné.
Edit: Ještě doplním, že velkou nevýhodou tohoto řešení, je držet cache aktualizovanou. Ve finále to zas takový problém není. V modelu si na metody update a delete musíš navěsit callbacky, které ti pozmění i pole v té cache pro routování.
Editoval Vyki (25. 2. 2011 14:29)
- Inferi
- Člen | 18
Děkuji za pomoc,
ještě jsem prohledával fórum a našel tento
příspěvek, který mě osobně funguje. Nicméně doufal jsem
v jednodušší řešení s příchodem Nette 2.