Použití globálního filtru pro vícejazyčnou aplikaci

pux
Člen | 14
+
0
-

Snažím se nastavit router tak, aby byl schopen generovat adresy pro českou i anglickou verzi ve formátu:

example.com/
example.com/en/

example.com/clanky/
example.com/en/articles/

example.com/kontakt/
example.com/en/contact/

Obsah je totožný a veškerý překlad je pouze v šablonách přes Translator, takže obě jazykové verze zpracovává vždy stejný presenter. V menu mám odkazy na přepínání české a anglické verze pro aktuální stránku (tj. stejně, jak to funguje na webu Nette):

<a n:href="this locale => 'cs'">CZ</a> / <a n:href="this locale => 'en'">EN</a>

A moje routa zatím vypadá takto:

$router->addRoute('[<locale=cs [cs|en]{2}>/]<presenter>[[/<id>]/<action>]', [
    'presenter' => 'Homepage',
    'action' => 'default',
]);

Problém je s tím, že když jsem třeba na stránce kontakt, tak mi to správně pro českou verzi generuje example.com/kontakt/, ale pro anglickou example.com/en/kontakt/ a já bych potřeboval example.com/en/contact/. Dočetl jsem se, že přesně toto mají řešit globální filtry, ale nemůžu pochopit, jakým způsobem v nich říct, aby pro anglickou verzi bylo v adrese contact, které ale bude zpracovávat KontaktPresenter.
Když si totiž v Route::FILTER_IN a Route::FILTER_OUT dumpnu $params, nikde tam možnost přepsat kontakt > contact nevidím, je tam jen název prezenteru, locale, action a ID.

null => [
    Route::FILTER_IN => function (array $params): array {
        bdump($params, 'IN');
        return $params;
    },
    Route::FILTER_OUT => function (array $params): array {
        bdump($params, 'OUT');
        return $params;
    },
],

Stránek mám pár a jsou statické, takže mi to nebude vadit zapsat ručně, ale nevím, kde právě říct “Pokud locale == "en", tak místo kontakt generuj contact.

David Matějka
Moderator | 6406
+
+1
-

Ahoj, ono je trochu matoucí, že v tom „presenter“ klíči máš přímo název presenteru „Kontakt“, ale v url vidíš slug „kontakt“, to ale dělá nette dalšími filtry (konkrétně presenter2path). Ale když v tom OUT filteru přepíšeš ten klíč presenteru na „contact“, tak to bude fungovat. (a v IN zas pak přeložíš contact na kontakt)

pux
Člen | 14
+
0
-

@DavidMatějka pecka, díky. Funguje přesně jak jsem potřeboval. Tohle mě nenapadlo, že to stačí jenom přepsat. Přidávám tedy pro budoucí generace funkční řešení:

null => [
    Route::FILTER_IN => function (array $params): array {
        if ($params['locale'] == 'en') {
            switch ($params['presenter']) {
                case 'Contact': $params['presenter'] = 'Kontakt'; break;
            }
        }
        return $params;
    },
    Route::FILTER_OUT => function (array $params): array {
        if ($params['locale'] == 'en') {
            switch ($params['presenter']) {
                case 'Kontakt': $params['presenter'] = 'Contact'; break;
            }
        }
        return $params;
    },
],