Překlad konkrétního slova v routě

před 6 měsíci

Gappa
Člen | 40
+
0
-

Ahoj,

snažil jsem se najít na fóru něco podobného, kde by toto bylo vyřešeno (a já pochopil jak), ale zatím bez úspěchu.

O co jde:

Mám např. takovouhle routu:

<?php
$router[] = new Route('[<locale=cs [cs|en|hu]{2}>/]produkt/<productId>/', 'Products:detail');
?>

(K té existuje ještě obecná, která je definovaná až za touto – klasická [<locale=cs [cs|en|hu]{2}>/]<presenter=Homepage>/<action=default>/[<id>/][<param>/]/)

Jde o to, aby v ostatních jazycích bylo místo produkt překlad pro daný jazyk, tj. product/termek, ale routa se nemusela definovat znovu pro každý jazyk.

Jak dynamicky přeložit <presenter> nebo <action> vím – toho jsem docílil přes globální filtry, kde znalostí locale předám do FILTER_TABLE pole překladů pro daný jazyk. Ale tohle mi zatím nějak uniká, jak správně řešit.

Kdysi jsem to řešil tak, že jsem v routeru z HTTP požadavku získával URL, z něj jazyk a pak přímo na míru tvořil dané routy, ale to nebylo dobré řešení…

Koukal jsem například na tyto odkazy:

Nejblíže je asi toto:

Ale tam jsem nepochopil, jak je by mělo fungovat udělat z toho search stringu v routě parametr a jak s tím případně dál pracovat.

Předem děkuji za jakékoliv rady nebo nakopnutí správným směrem! :)

před 6 měsíci

Felix
Člen | 832
+
+1
-

Ahoj, nejsem si uplne jistej zapisem, ale pouzil bych globalni filtr (https://doc.nette.org/cs/2.4/routing#…), cili NULL.

$router[] = new Route('[<locale=cs [cs|en|hu]{2}>/]<section=produkt>/<productId>/', [
    'presenter' => 'Products',
    'action' => 'detail',
    NULL => [
        Route::FILTER_IN => function (array $params) {
            // ...
            $params['section'] = $sections[$params['locale']];
            return $params;
        },
        Route::FILTER_OUT => function (array $params) {
            // ...
            $params['section'] = $sections[$params['locale']];
            return $params;
        },
    ],
]);

Snad to nejak pomuze.

před 5 měsíci

Gappa
Člen | 40
+
0
-

Tak se mi to asi podařilo nějak provizorně splácat dohromady :)

RouterFactory

$router[] = $front = new RouteList('Front');

$front[] = $this->router->create('<section>/<mainCategorySlug>/<productSlug>-p<productId [0-9]+>/', [
    'presenter' => 'Products',
    'action' => 'product',
]);

$front[] = $this->router->create('<section>/<mainCategorySlug>/<categorySlug>-c<categoryId [0-9]+>/', [
    'presenter' => 'Products',
    'action' => 'category',
]);
$front[] = $this->router->create('<section>/<mainCategorySlug>/', [
    'presenter' => 'Products',
    'action' => 'mainCategory',
]);

...

$front[] = $this->router->create('<presenter=Homepage>/<action=default>/[<id>/][<param>/]');

Router
Třída Router (volání $this->router->create()) pomáhá vytvářet zbytek – např. automaticky vkládá na začátek masky jazykovou část routy (v tomto případě [<locale=cs [cs|en|hu]{2}>/])

Abych ji sem nekopíroval celou – pokud najde v masce <section>, tak se aplikuje upravený globání filter, který se podívá, jestli v překladovém poli je příslušný klíč/hodnota (podle směru, tj. in/out), směrodatný je v tomto ohledu $params['presenter'].

FilterIn:
V případě filterIn je v $params['section'] obsažená hodnota, která se nejprve najde v překladech a pak se porovná s názvem presenteru, na který by sekce měla směřovat, pokud se shodují, pak routa vyhovuje a použije se – tím se zajistí, aby takových rout mohlo vedle sebe být více.

FilterOut:
Funguje obdobně, pokud se najde v překladech pro cílový presenter přeložená sekce, do $params['section'] se tato hodnota podle aktuální jazyka vloží.

Překladové pole vypadá třeba takto, ve formátu “url – presenter/sekce”, zde v NEON formátu:

cs:
    presenter:
        'katalog': 'Products'
        'skoleni': 'Seminars'
        'clanky': 'Articles'
        'cenik': 'Pricelist'
        'akce': 'Promos'

Následuje pak i podpole “actions” – to je kvůli tomu, že to stejné pole se používá pro překlad presenterů a akcí.

Co se kvality kódu týče, tak to zatím mám dost neučesané, ale zdá se, že to takto funguje :) Univerzální to rozhodně není, prostor pro vylepšení je vždy.

Proč to sem celé takto popisuji? Nemám rád dotazy, kde tazatel už se pak vůbec neozve, nebo jen napíše “díky, vyřešeno” bez jakýchkoliv dalších informací, které by mohly pomoct někomu dalšímu :)

Děkuji uživateli @Felix za nakopnutí :)