Vícejazyčná routa s výchozím jazykem, na který se přesměruje, pokud není uveden

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

Ono to bude hodně jednoduché, ale jdu na to asi ze špatného konce.
Mám jednoduchý případ webu, kde přidávám dodatečně jazyky. Cíl je tento:
meltdown.cz/cs/ nebo meltdown.cz/en/ a pokud někdo zavolá meltdown.cz, vyhodnotí se jeho jazyková preference dle $_SERVER[‚HTTP_ACCEPT_LANGUAGE‘] a nasměruje se na jeden z předchozích.

Takže v routě nebude „locale“ povinné, ale doplní se.

Routu jsem udělal (je jediná):

$router[] = new Route('[<locale cs|en>/]<presenter>/<action>[/<id>]', 'Homepage:default');

A do BasePresenteru jsem hodil (zkráceně):

	/** @persistent */
	public $locale;

	public function startup() {
		parent::startup();
		if ($this->locale == NULL) {
			if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE']) && substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2) == 'en') {
				$this->redirect('this', ['locale' => 'en']);
			} else {
				$this->redirect('this', ['locale' => 'cs']);
			}
		}
	}

První dojem byl dobrý. Detekce jazyka vypadala funkční a „skoro nic“ se nerozbilo.
Nefungují mi najednou error-presentery: dostanu se do nějakého redirect-loopu (místo 404 se po redirectu na /cs/error4xx/ nenačte nic a při dalším načtení něčeho funkčního si v Laděnce přečtu že proběhlo asi 10 přesměrování na Error4xx:default po 120 milisekundách).

Testoval jsem pokusem (předtím to fungovalo) a došel k tomu, že ten můj zásah v BasePresenteru je příčinou.

Než bych tu prosil a doladění své konkrétní trable, asi bude lepší, když byste mi někdo, prosím, napsal, jestli to nemám řešit úplně jinak, např. pomocí dvou rout.

Díky, Richard

Editoval BayerMeister (17. 5. 2017 13:09)

BayerMeister
Člen | 10
+
0
-

Provizorně pojedu na zjednodušeném modelu. Routy mám:

<?php
$router[] = new Route('<locale cs|en>/<presenter>/<action>[/<id>]', 'Homepage:default');
$router[] = new Route('<presenter>/<action>[/<id>]', ['presenter' => 'Homepage', 'action' => 'default', 'locale' => 'cs'], Route::ONE_WAY);
?>

A „locale resolver“, tj. to, co jsem měl v BasePresenteru->startup(), jsem dočasně vyřadil.
Je to čistý, ale chtěl jsem tu detekci jazyka dle HTTP_ACCEPT_LANGUAGE.

Thoughts welcome. Díky

duke
Člen | 650
+
0
-

Z toho, co uvádíš se zdá, že Error presentery nepodporují persistentní parametry. Už se to řešilo před časem tady, ale není mi jasné, zda a jak se to vyřešilo.

Nicméně ErrorPresenteru se posílá v parametrech poslední (chybu způsobující) request, ze kterého by to locale mohlo jít vytáhnout.

Editoval duke (18. 5. 2017 14:42)

galab
Backer | 74
+
0
-

Nepomohlo by ti třeba?

$httpRequest->detectLanguage();
BayerMeister
Člen | 10
+
0
-

Kurňa, měl jsem vypnuté notifikace o odpovědích a měl za to, že nikdo neodpověděl.
Díky, detectLanguage() je to, co jsem si zbytečně napsal sám. Použiju to.
Otázka zůstává, kam to v kódu zařadit.

Je dobré na to mít samostatnou routu (ta ONE_WAY v příkladu výše) a namířit to na speciální akci, která to jednoduše redirectne na hlavní routu?
Abych se nedostal do nesnází s error presentery nebo odkazování souborů/obrázků atp.
A čekal by mě pokus-omyl, jak zachovat všechny přidané parametry (za otazníkem)…

Díky, už budu reagovat pružně, snad.