Routování domény 3tího řádu
- ondraLE
- Člen | 23
Ahoj, mám projekt, který má jednotlivé „klienty“ rozhozeny dle
domény 3tího řádu, např klient1.domena.cz, a klient2.domena.cz.
V routeru mám funkční nastavení takto:
$router->addRoute('<locale>/<module>/<presenter>/<action>[/<id>]', [
'locale' => [
Route::Value => 'cs',
Route::FilterIn => fn($locale) =>!is_null($locale) ? $locale : 'cs',
],
'module' => 'Basic',
'presenter' => 'Home',
'action' => 'default',
'id' => null,
]);
pokud bych chtěl dle návodu přidat rozlišení domény, zkoušel jsem toto, ale pokaždé route not found:
$router->addRoute('<client>\.%domain%/<locale>/<module>/<presenter>/<action>[/<id>]', [
'locale' => [
Route::Value => 'cs',
Route::FilterIn => fn($locale) =>!is_null($locale) ? $locale : 'cs',
],
'client' => 'Defaultclient',
'module' => 'Basic',
'presenter' => 'Home',
'action' => 'default',
'id' => null,
]);
Tušíte kde je problém?
Pak druhá věc, pokud se rozběhne správné routování a identifikace
klienta, potřebuji aby např. obrázky typu .jpg, se automaticky načítaly
z jiné složky. Fyzicky jsou uloženy
v appDir/files/{client}/cokoli.jpg,
routa:
$router->withPath("files")->addRoute("[<folder>/]<filename>", function ($filename, $folder = ""){
echo $filename. "- ".$folder."\n";
});
Zde bude stačit přímo načíst readfile z dané složky a poslat? Tedy
hledal bych file: www/files/{client}/{folder}/{filename} nebo
je
lepší na soubor provést redirect? Jde mi o to, že pokud jsou připojeny
např. obrázky, aby fyzická cesta k souboru byla „schována“ za tento
formát.
Díky za rady.
- m.brecher
- Generous Backer | 864
@ondraLE
pokaždé route not found:
Zkus vynechat to zpětné lomítko:
// tvůj kód
$router->addRoute('<client>\.%domain%/<locale>/<module>/<presenter>/<action>[/<id>]', .....)
// zkus toto:
$router->addRoute('<client>.%domain%/<locale>/<module>/<presenter>/<action>[/<id>]', .....)
// nebo natvrdo doménu:
$router->addRoute('<client>.mojedomena.cz/<locale>/<module>/<presenter>/<action>[/<id>]', .....)
- ondraLE
- Člen | 23
m.brecher napsal(a):
// tvůj kód $router->addRoute('<client>\.%domain%/<locale>/<module>/<presenter>/<action>[/<id>]', .....) // zkus toto: $router->addRoute('<client>.%domain%/<locale>/<module>/<presenter>/<action>[/<id>]', .....) // nebo natvrdo doménu: $router->addRoute('<client>.mojedomena.cz/<locale>/<module>/<presenter>/<action>[/<id>]', .....)
lomítko nepomohlo, nemůže to být tím, že tam mám ještě číslo portu? běží mi to na 8888 a localhostu, tak nevím, zda správně přeloží %domain% i jako localhost
Editoval ondraLE (16. 4. 8:08)
- m.brecher
- Generous Backer | 864
@ondraLE
běží mi to na 8888 a localhostu
Jestli to provozuješ na lokálním serveru, tak tam subdoménu asi nastavit nepůjde. Tam můžeš mít jenom http://localhost/… Můžeš to zkusit vyřešit tak, že si uděláš dvě různé routy pro lokální vývoj a pro produkční nasazení – cca nějak takto:
if($_SERVER['REMOTE_ADDR'] === '127.0.0.1'){
router->addRoute('<client>/<locale>/<module>/<presenter>/<action>[/<id>]', .....)
}else{
router->addRoute('<client>.mojedomena.cz/<locale>/<module>/<presenter>/<action>[/<id>]', .....)
}
- ondraLE
- Člen | 23
perfekt, to funguje, díky! a pak mám poslední dotaz. dělám projekt,
který bude mít admin sekci, v url /admin/{jazyk}/modul/presenter/action
např. http://localhost:8888/admin/cs/cms/menu/
, zároveň
frontend, kde cokoli za lomítkem (nebude-li /admin) mi hodí na frontend
presenter, modulu front.
mám common.neon mapping takto:
mapping:
Front: App\Module\Front\Presenters\*Presenter
*: App\Module\Admin\*\Presenters\*Presenter
router:
public static function createRouter(): RouteList
{
$router = new RouteList;
$router->addRoute('admin/<locale>/<module>/<presenter>/<action>[/<id>]', [
'locale' => [
Route::Value => 'cs',
Route::FilterIn => fn($locale) =>!is_null($locale) ? $locale : 'cs',
],
'module' => 'Basic',
'presenter' => 'Home',
'action' => 'default',
'id' => null,
]);
$router->withModule("Front")->addRoute('<locale>/<link>[/<id>]', [
'locale' => [
Route::Value => 'cs',
Route::FilterIn => fn($locale) =>!is_null($locale) ? $locale : 'cs',
],
'link' => 'Home',
'presenter' => 'Frontend',
'action' => 'default',
'id' => null,
]);
return $router;
}
Potíž je v tom, že když zavolám
localhost:8888/admin/cs/cms/menu/
správně do jde na routu admin a
vše funguje,
pokud zavolám: localhost:8888/cs/test
, skočí mi to sice na
správný frontend presenter, ale URL přesměruje na admin:
localhost:8888/admin/cs/front/frontend/?link=test
, netuším proč
to přesměrovává.
update:
pokud přehodím pořadí rout, a upravím tu veřejnou takto:
$router->withModule("Front")->addRoute('<locale>/<link[test]>[/<id>]', [...
tak to sice funguje jak má, nicméně posílá se mi pak parametr
link[admin]=test, viz:
Front:Frontend:default
locale = cs
link[admin] = test
link = Home
id = null
Editoval ondraLE (16. 4. 21:20)
- m.brecher
- Generous Backer | 864
@ondraLE
netuším proč to přesměrovává. Byla by rada?
Routy Nette jsou v tomhle trochu záludné. Nette totiž aplikuje dvě různá pravidla po sobě, a člověka občas překvapí právě takovéto přesměrování. První pravidlo je – první routa která matchne url se použije. Druhé pravidlo je, že presenter získaný request ověřuje na duplicitu a zkusí z něj LinkGenerátorem vygenerovat link. Pokud se liší od původního url, přesměruje na něj – je to totiž kanonické url.
A když se podívám do Tvojí routy, tak tam duplicita url vidět je:
// matchne jakýkoliv modul a jakýkoliv presenter
$router->addRoute('admin/<locale>/<module>/<presenter>/<action>[/<id>]'
// matchne presentery v modulu Front
$router->withModule("Front")->addRoute('<locale>/<link>[/<id>]'
Takže když máš link na druhou routu, tak LinkGenerátor přesměruje na první, která ten request také matchne – je první, proto je kanonická.
Musíš vyloučit v obecném pravidle pro modul v první routě modul Front:
$router->addRoute('admin/<locale>/<module (?!front).*>/<presenter>/<action>[/<id>]'
- Kamil Valenta
- Člen | 815
m.brecher napsal(a):
Jestli to provozuješ na lokálním serveru, tak tam subdoménu asi nastavit nepůjde. Tam můžeš mít jenom http://localhost/…
To úplně ne. „Lokální“ server se možnostmi konfigurace nijak
neliší od produkčního či jiného.
Ba naopak, mrskat vícero projektů na http://localhost/<něco> musí být docela opruz.
Někteří si jednotlivé hosty pojmenovávají „fiktivními“ doménami
s TLD .loc nebo .local,
ale v zásadě si člověk může nastavit TLD klidně .cz a v host souboru si
doménu nasměrovat na 127.0.0.1
- ondraLE
- Člen | 23
m.brecher napsal(a):
@ondraLE
netuším proč to přesměrovává. Byla by rada?
Routy Nette jsou v tomhle trochu záludné. Nette totiž aplikuje dvě různá pravidla po sobě, a člověka občas překvapí právě takovéto přesměrování. První pravidlo je – první routa která matchne url se použije. Druhé pravidlo je, že presenter získaný request ověřuje na duplicitu a zkusí z něj LinkGenerátorem vygenerovat link. Pokud se liší od původního url, přesměruje na něj – je to totiž kanonické url.
A když se podívám do Tvojí routy, tak tam duplicita url vidět je:
// matchne jakýkoliv modul a jakýkoliv presenter $router->addRoute('admin/<locale>/<module>/<presenter>/<action>[/<id>]'
// matchne presentery v modulu Front $router->withModule("Front")->addRoute('<locale>/<link>[/<id>]'
Takže když máš link na druhou routu, tak LinkGenerátor přesměruje na první, která ten request také matchne – je první, proto je kanonická.
Musíš vyloučit v obecném pravidle pro modul v první routě modul Front:
$router->addRoute('admin/<locale>/<module (?!front).*>/<presenter>/<action>[/<id>]'
funguje! díky moc!
Lze ještě do routeru injektovat nějakou továrnu, ve které mám nastaven nějaký parametr, kterých bych rád využil u vlastního filtru routeru (Route::FilterIn =>fce) ?
- m.brecher
- Generous Backer | 864
@ondraLE
Lze ještě do routeru injektovat nějakou továrnu … ?
Ano, s využitím potenciálu Nette DI, např:
services:
- App\Router\RouterFactory::createRouter(@App\Components\Provider)
- App\Components\Provider
public static function createRouter(App\Components\Provider $provider): RouteList
{
// zde $provider použiješ
}
- ondraLE
- Člen | 23
m.brecher napsal(a):
@ondraLE
Lze ještě do routeru injektovat nějakou továrnu … ?
Ano, s využitím potenciálu Nette DI, např:
services: - App\Router\RouterFactory::createRouter(@App\Components\Provider) - App\Components\Provider
public static function createRouter(App\Components\Provider $provider): RouteList { // zde $provider použiješ }
že mě to nenapadlo, opět funkční, díky!