routování podle konkrétního presenteru
- Oli
- Člen | 1215
Jde nějak routovat podle presenteru? Myslím tím, mít někde nahoře routu, která se provede jen když je aktivní nějaký presenter, např PagePresenter. Pokud není aktivní PagePresenter, tak se routa neprovede i když maska vyhovuje.
Např: Teď mám 2 routy a ty fungujou:
$pageRoute = new PageRoute('<id>', array(
'presenter' => 'pages',
'action' => 'detail',
...
));
$router[] = $pageRoute;
$router[] = new Route('<presenter>/[<action=default>]', array(
...
));
Potřeboval bych mít ale v první routě jeden nepovinný parametr, něco jako:
$pageRoute = new PageRoute('[<parent>]<id>', array(
'presenter' => 'pages',
'action' => 'detail',
...
));
$router[] = $pageRoute;
$router[] = new Route('<presenter>/[<action=default>]', array(
...
));
Pokud to udělám takhle, tak mě všechny dotazy spadnou na první routu, protože má nějaké dva parametry. Já bych ale potřeboval aby se první routa vykonala jen, když bude presenter Pages. Zároveň, ale nechci mít název presenteru v URL.
Lze to nějak udělat, nebo mám blbě návrh rout?
Díky.
- BigCharlie
- Člen | 283
V tom druhém případě to není možné napsat takhle obecně. Které
routě by podle tebe vyhověla adresa http://tvuj.web/cokoliv
?
Nette bere vždy první routu, která vyhoví (ostatně v route debuggeru máš určitě u té druhé routy poznámku matched – may). Jak má poznat, kdy se jedná o id z první routy, nebo presenter z druhé routy?
V takovémhle případě buď musíš udělat specifičtější routu (tedy doplnit Pages do routy), nebo si napsat vlastní router.
Lepší řešení neznám, třeba mě někdo opraví…
- Oli
- Člen | 1215
No právě, na to se ptám. Jestli jde nějak říct, že v tý první routě ty dva parametry jsou parametry a ne název routy nebo akce.
Jestli existuje něco jako, já nevím, například:
$pageRoute = new PageRoute('<id>', array(
'presenter' => 'pages',
'action' => 'detail',
...
), PagePresenter);
Prostě, že by se podivalo do ty routy jen, kdyby se mel vykonat PagePresenter, jinak jet dal… Asi to je takhle blbost, jen se ptam, jstli nahodou něco takovýho neexistuje :-)
Vlastní router jsem si napsal podle přednášky Honzy Smitka:
class PageRoute extends \Nette\Application\Routers\Route
{
/** @var \PageModel */
private $page;
public function match(\Nette\Http\IRequest $httpRequest)
{
/**
* @var \Nette\Application\Request
*/
$appRequest = parent::match($httpRequest);
if ($appRequest != null && !is_numeric($appRequest->parameters['id']))
{
$page = $this->page->getBySlug($appRequest->parameters['id']);
if (!$page)
{
return null;
}
$params = $appRequest->parameters;
$params['id'] = $page->id;
$appRequest->parameters = $params;
}
return $appRequest;
}
}
Když to nějak rozšířím, tak tam můžu dostat ty dva parametry, který budou vidět v url, ale nebudou v masce? Nebo jsi to myslel jinak s tím napsáním vlastního routeru?
V podstatě chci výstup:
JakykoliPresenter:NejakaAkce
neco.cz/jakykoliPresenter/nejakaAkce // Standardní chování, pokud není presenter PagePresenter
PagePresenter/detail $dite
neco.cz/slug-ditete
PagePresenter/detail $rodic, $dite
neco.cz/slug-rodice/slug-ditete
Je to vubec mozny?
Diky
- Tori
- Člen | 32
Jestli jde nějak říct, že v tý první routě ty dva parametry jsou parametry a ne název routy nebo akce
Kolik je těch ostatních presenterů? Možná by to šlo takhle:
// nejdřív vyjmenovat všechny ostatní presentery
$router[] = new Route('<presenter x|y|z>/[<action=default>]');
// všechno ostatní spadne presenteru Page
$router[] = new Route('<parent>[/<id>]', array(
'presenter' => 'Page',
'action' => 'default',
));
- llsm
- Člen | 121
A co takhle bez pouziti? (psano z hlavy)
<?php
//Vsechno, co je na strance Page:Detail, child je povinny, parent volitelny parametr
$router[] = new Route('[<parent>/]<child>', array(
'presenter' => 'Page',
'action' => 'detail',
'child' => array(
//Filtry pro prekladani slugu
Route::FILTER_IN => callback('SlugToID'),
Route::FILTER_OUT => callback('IDToSlug'),
),
'parent' => array(
//Filtry pro prekladani slugu
Route::FILTER_IN => callback('ParentSlugToID'),
Route::FILTER_OUT => callback('ParentIDToSlug'),
),
));
// Co nevyhovi predchozim routam, spadne do obecne
$router[] = new Route('<presenter>/[<action=default>]', array(
...
));
?>