GET parametr action koliduje s action presenteru

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

Zdravím,
potřeboval bych udělat relativně jednoduchou routu, kde bych vše začínající na /nazev řešit jednou akcí jednoho presenteru. Zatím jednoduché. Ale potřebuji, aby to fungovalo korektně i s GET parametrem action, tedy aby to jej nebralo za nějaký speciální parametr. (Nemám moc možností to změnit.) Bohužel, pokud je v URL tento GET parametr, udělá to nežádoucí redirect.

Druhá varianta byla vlastní routa. Měl jsem tam ale trošku problém správně napsat reverzní routování, aby to fungovalo i s callbackem u formuláře. Hlavně jsem nepochopil druhý parametr metody Nette\Application\IRouter::constructUrl(Nette\Application\Request $appRequest, Nette\Http\Url $refUrl). Dokumentaci jsem četl, ve fóru jsem hledal, ale nic jsem k tomu pořádně nenašel.

enumag
Člen | 2118
+
0
-

Názvy těch parametrů jsou v Nette docela napevno zadrátované. Vlastní router by ti pravděpodobně nepomohl. Vřele doporučuji neřešit to a použít jiný název parametru.

Michalek
Člen | 211
+
0
-

Co přidat do routeru ?action=<mujnazev>

Pak by se k action parametru přistupovalo přes getParam('mujnazev') a action by zůstala „neporušená“?

v6ak
Člen | 206
+
0
-

Zkoušel jsem to routovat i s action, ale nepomáhá:

$container->router[] = new Route('prefix[/<a .*>]', array(
        'module' => ...,
        'presenter' => ...,
        'action' => :...
	));
$container->router[] = new Route('prefix[/<a .*>]?action=<b .*>', array(
        'module' => ...,
        'presenter' => ...,
        'action' => ...
	));

Změnit název parametru bohužel nejde, minimálně v adrese musí zůstat.

Vlastní router na toto pomáhá (aplikace dál čte z adresy, takže se to neprojevuje jako action, jen v GET), ale způsobuje jiné problémy, které vznikly asi nepochopením onoho druhého parametru metody constructUrl:

class PrefixRouter implements Nette\Application\IRouter{

	private $addr;

	public function __construct($prefix){
		$this->addr = $prefix;
	}

    function match(Nette\Http\IRequest $httpRequest){
		$addr = $this->addr;
		$url = $httpRequest->getUrl();
		if( ($url->getPathInfo() == $addr) || (substr($url->getPathInfo(), 0, strlen($addr)+1) == $addr.'/') ){
			return new \Nette\Application\Request(..., $httpRequest->getMethod(), array(
				'action'=>...,
				'path'=>$url->getPath(),
				'query'=>$url->getQuery()
			));
		}
	}

    function constructUrl(Nette\Application\Request $appRequest, Nette\Http\Url $refUrl) {
		if($appRequest->getPresenterName() == 'Front:Diskuse'){
			$params = $appRequest->getParameters();
			return $params['path'].'?'.$params['query'];
		}
	}

}

Problém nastane, když mám na každé stránce nějaký kontaktní formulář. Ten je pak odesílán na nesprávnou URL (action=„?“), protože

  • Metoda constructUrl nedostane parametry path ani query. (Nevím proč.)
  • Metoda constructUrl zde trošku nerespektuje, že má přidat nějaké další parametry, moje chyba.

Hlavně jsem nepochopil, jak mám interpretovat ten druhý parametr, dokumentaci jsem nenašel. Rád si to opravím sám, pokud mi někdo prosím řeknete, jak mám chápat ten druhý parametr.

Editoval v6ak (6. 2. 2013 12:04)

Tomáš Votruba
Moderator | 1114
+
0
-

Kdyby se ti nedařilo problém vyřešit, tak můžeš při nejhorším v index.php (či jinde před načtením Nette) natvrdo přesměrovat z ?action=sth na ?paramAction=sth. Pokud tedy můžeš měnit název přijímaného parametru (nevím, co všechno měnit nemůžeš).

Editoval Schmutzka (6. 2. 2013 16:55)

llook
Člen | 407
+
0
-

Přejmenování action parametru v routě funguje, teď jsem to zkoušel:

$container->router[] = new Route('prefix ? action=<foo>', 'Homepage:default');

Tenhle kód v šabloně Homepage/default.latte mi potom normálně vytvoří odkaz /prefix?action=asdf:

<a n:href="this, foo => asdf">odkaz</a>

Tak nevím, v čem je problém.

pekelnik
Člen | 462
+
0
-

@v6ak: Mam za to ze druhy parametr constructUrl() slouzi ke konstrukci relativnich odkazu.

v6ak
Člen | 206
+
0
-

@Schmutzka: Díky, to bude už celkem tvrdé ohackování…

@llook: Tak jsem to zkusil ještě jednou a přišel jsem na zajímavý poznatek: Pokud je v URL jen parametr action, funguje to. Ale pokud jsou za ním ještě nějaké další parametry, pak už to nefunguje. Ani pokud to přidám do routy jako další část.

@pekelnik: No, to je takové zajímavé. Ve chvíli, kdy to kanonizuje URL, mám ve druhém parametru cestu na homepage. Pokud ale počítám cestu k action formuláře na té stránce, mám ve druhém parametru cestu na aktuální stránku a v prvním parametru nemám parametry aktuální stránky. Šlo by to z toho vyhackovat, ale naznačuje to, že té stručné dokumentaci až tak nerozumím.