Router pro presenter z db

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

Dobrý den,
potřeboval bych poradit se směrováním.

Mám nastaveny routy:

$adminRouter[] = new Route('admin/content/<page_id>/[<method>/][<article_id>/]', 'Content:default');
$adminRouter[] = new Route('admin/<presenter>/<action>/[<id>/]', 'Default:default');

Druhá routa funguje bez problému.

Problém mám stou první. Potřebuji aby při zadání domena.tld/admin/content/5/edit/10/ bylo z db zjištěno (podle page_id) jaký presenter se má použít a akci předat page_id a article_id.

Zkusil jsem to vyřešit vytvořením ContentPresenter a v jeho actionDefault (přes model) jsem se dotázal do databáze na presenter u požadovaného záznamu. A poté pomocí $this->forward($presenter.‚:‘.$method, $page_id, $article_id) spustil příslušný presenter. To omezeně fungovalo, problém nastal pokud nebylo $article_id definováno. Nemluvě o zpětném generování url, které nefungovalo vůbec.
Toto řešení mi stejně nepřišlo vůbec dobré, jen mě zrovna nic jeného nenapadlo, tak jsem chtěl zkusit jak se to bude chovat.

Ideální by asi bylo použít něco takového?

$adminRouter[] = new Route('admin/content/<page_id>/[<action>/][<article_id>/]', 'Presenter:default');

A přímo v routeru pomocí modelu detekovat jaký presenter se bude používat (bez ContentPresenter). S tím si ale nevím nějak rady :-/

Za jakékoliv navedení děkuji.

sKopheK
Člen | 207
+
0
-

Zkusil bych to pres FILTER_IN
https://doc.nette.org/…tion/routing#…

jEhLa
Člen | 70
+
0
-

To už mě také napadlo, zkoušel jsem:

$adminRouter[] = new Route('admin/content/<page_id>/[<action>/][<article_id>/]',array(
	'presenter' => array(
		Route::FILTER_IN => function($page_id) { return "Blog"; }
	),
	'action' => 'default'
));

Natvrdo jsem si nastavil hodnotu kterou by to mohlo vracet. Ale ať jsem zkoušel za FILTER_IN udělat cokoliv, tak se to chová furt stejně.
V tomto případě to vrátí: Missing presenter in route definition.
Tak jsem jen zkusil přepsat „page_id“ v routě na „presenter“. A pak to zase vrátí: No route for HTTP request.

Už se vtom vrtám tak dlouho že jsem ztoho celej domotanej :-/

David Matějka
Moderator | 6445
+
0
-

pouzij ten globalni fitlr, tedy

array(
	NULL => array(
		Route::FILTER_IN ....
	)
)

ten muze prijima vsechny parametry a vsechny parametry muze upravit

sKopheK
Člen | 207
+
0
-

Řekl bych, že takto můžeš přepsat pouze hodnotu presenteru podle hodnoty předané v URL, v tomto případě v routě žádný parametr pro presenter nemáš. Název proměnné předávané funkci nesouvisí s proměnnou v routě. Podle tutoriálu bys měl FILTER_IN hodit pro všechny parametry, např.

$route = new Route('admin/content/<page_id>/[<action>/][<article_id>/]', array(
    'presenter' => 'Homepage',
    'action' => 'default',
    NULL => array(
        Route::FILTER_IN => function(array $params) {
            // ...
            return $params;
        },
    ),
));

a jak tam řešit třeba dotaz na DB se tu někde řešilo na fóru.

jEhLa
Člen | 70
+
0
-

Jé, konečně jsem se pohnul z místa. Děkuji

Toto funguje:

$adminRouter[] = new Route('admin/content/<page_id>/[<action>/][<article_id>/]',array(
	'presenter' => null,
	'action' => 'default',
	null => array(
		Route::FILTER_IN => function(array $params) {
			$params['presenter'] = $this->pageModel->getPagePresenter( $params['page_id'] );
			return $params;
		},
	)
));

Ale objevil se hned další problém.

  • Pokud tam nebylo zadáno to ‚presenter‘ ⇒ null, tak se stránka redirectovala na url: domena.tld/admin/content/20/?presenter=Blog
  • Když je definováno ‚presenter=null‘ url se redirectuje na: domena.tld/admin/blog/?page_id=20

Dělá to ta druhá nastavená routa:
$adminRouter[] = new Route(‚admin/<presenter>/<action>/[<id>/]‘, ‚Default:default‘);
Pokud ji odstraním tak vše funguje bez problému.

Jak docílit toho aby se stránka nepřesměrovávala a zůstala na domena.tld/admin/content/20/?

Editoval jEhLa (9. 4. 2014 14:37)

sKopheK
Člen | 207
+
0
-

Zkus obraceny proces ve FILTER_IN, aby se URL shodovaly.

llsm
Člen | 121
+
0
-

Zdravím, co nějak takto:

<?php
$adminRouter[] = new Route('admin/content/<page_id>/[<action>/][<article_id>/]',array(
    'presenter' => null,
    'action' => 'default',
    null => array(
        Route::FILTER_IN => function(array $params) {
            $params['presenter'] = $this->pageModel->getPagePresenter( $params['page_id'] );
            return $params;
        },
	 Route::FILTER_OUT => function(array $params) {
            $params['presenter'] = null;
            return $params;
        },
    )
));
?>

Ten FILTER_IN ti nastavil param['presenter'] a vzhledem k tomu, ze jsi ho nemel v route zakomponovany, tak tam vylezl jako klasicky GET parametr. Myslim, ze pokud ho ve FILTER_OUT nastavis zpatky na null, tak by to mohlo byt ok. Zatim jsem osobne nenarazil na pripad, kdy bych prekladal neco jen jednim smerem, vzdy obema.

jEhLa
Člen | 70
+
0
-

Děkuji moc lidi.

Toto je konečně funkční.

$adminRouter[] = new Route('admin/content/<page_id>/[<action>/][<article_id>/]',array(
	'action' => 'default',
	null => array(
		Route::FILTER_IN => function(array $params) {
			$params['presenter'] = $this->pageModel->getPagePresenter( $params['page_id'] );
			return $params;
		},
		Route::FILTER_OUT => function(array $params) {
			$params['presenter'] = null;
			return $params;
		}
	)
));

Stačilo tedy k tomu použít ještě ten FILTER_OUT a odebrat ten výchozí ‚presenter‘=>null.

Ještě jednou díky