Routování více domén podle id v databázi

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

Zdravím všechny, pokouším se už druhý den experimentovat s routami, ale bez úspěchu. Ve fóru jsem nenašel řešení a proto se chci zeptat:

  1. hlavní aplikace jede na doméně www.mujprofil.cz
  2. uživatel si bude moct založit profil který bude dostupný na <id>.mujprofil.cz
  3. současně ale uživatel může nasměrovat na svůj profil svou vlastní doménu (alias pomocí A záznamu) např. www.frantisek.cz

Potřebuji vytvořit routu, která odchytí doménu a defaultně zobrazí obsah, který je dostupný pod <id>.mujprofil.cz, tak aby adresa zůstala ve tvaru www.frantisek.cz pokud možno bez předaného <id>.

www.frantisek.cz bude tedy ekvivalentem pro frantisekovo-id-v-databazi.mujprofil.cz

Zkoušel jsem něco jako..

$router[] = new Route('//frantisek.cz[/<id>]', array(
	'presenter' => 'Card',
	'action' => 'default',
	'id' => 'frantisekovo-id-v-databazi',
	), Route::ONE_WAY);


$router[] = new Route('card/<id>', array(
	'presenter' => 'Card',
	'action' => 'default',
	'id' => NULL
	));

Nicméně tohle je ruční routování a kdybych to takto měl definovat pro všechny uživatele, tak je to nesmysl! Předpokládá se totiž 100–1000 profilů.

Znáte někdo nějaké efektivní řešení ?

Ot@s
Backer | 476
+
0
-

Použij na to vlastní překladové funkce a filtry (FILTER_IN/FILTER_OUT). Taky zvaž, jestli je dobré mít stejný obsah na 2 doménách (doporučuji zvolit jednu primární a druhou přesměrovávat na primární).

eudard
Člen | 15
+
0
-

Zkouším tohle..

$router[] = new Route('//<domain>', array(
        'presenter' => 'Card',
        'action' => 'default',
        'id' => array( Route::FILTER_IN => function($domain) {
					if ($domain=='frantisek.cz')
						return 'frantisekovo-id-v-databazi';
					},
        )), Route::ONE_WAY);

ale v presenteru je $this->getParameter(‚id‘) prázdné !
Jdu správnou cestou ?

Dokonce i tohle vrací prázdné id ..

$router[] = new Route('//<domain>', array(
        'presenter' => 'Card',
        'action' => 'default',
        'id' => array(
		Route::FILTER_IN => function($domain) { return "frantisekovo-id-v-databazi"; },
        	)
	), Route::ONE_WAY);

Editoval eudard (15. 3. 2012 10:53)

Jan Endel
Člen | 1016
+
0
-

Jenom se ptám, ale nemělo by se tohle řešit spíše pomocí CNAME záznamů?

eudard
Člen | 15
+
0
-

Aliasy jsou vyřešeny, to není třeba řešit, je to teď nastaveno tak, aby několik domén směřovalo na index hlavní domény.

hlavní doména je : mujprofil.local

domény například frantisek.local, anezka.local, nadezda.local jsou vyrobeny pomocí virtualhostu a po jejich zadání do prohlížeče se zobrazí mujprofil.local

takže vše jde na NETTE, to už mám vyřešeno, jen potřebuji odchytit název domény a rovnou zobrazit profil, který danému uživateli náleží.

  • mujprofil.local > Homepage:default
  • frantisek.local > Card:default, id=frantisek
  • anezka.local > Card:default, id=anezka

Editoval eudard (15. 3. 2012 11:05)

Ot@s
Backer | 476
+
0
-

@**Pilec** CNAME/A slouží pro směrování na IP serveru/hostingu. Na serveru pak webserver „asociuje“ takro příhoszí hostname s konkrétním prostorem. Tady se asi řeší to, že na stejné FTPko současně směřují domény test.domena.cz i www.test.cz – tedy otázka pro Nette.

@**eudard** Máš zaplý nette developerbar? Pokud ne, zapni si ho a koukej do něj – obsahuje krásnou routovací tabulku s informacema, které potřebuješ pro ladění/testování.

eudard
Člen | 15
+
0
-

Ot@s: panel samozřejmě používám, jen při zadání routy :

$router[] = new Route('//<domain>', array(
        'presenter' => 'Card',
        'action' => 'default',
        'id' => array(
                Route::FILTER_IN => function($domain) { return 12345; },
                )
        ), Route::ONE_WAY);

mi to v parametru id nevrátí nic.. Debugbar hlásí že routu použil, nicméně

Matched?:
Yes

Mask:
//<domain>

Defaults:
- presenter = Card
- action = default

Request:
- Card:default
- domain = anezka.local
Panda
Člen | 569
+
0
-

No protože nastavuješ filtr parametru id, ale v routě máš parametr domain. Nette nedokáže z názvu parametru té metody vycucat, že chceš ve skutečnosti id sestavovat podle hodnoty parametru domain. :-)

Řešení: použít masku //<id>. Mimochodem, aby fungovalo routování správně, budeš potřebovat i FILTER_OUT. Když použiješ jen FILTER_IN, tak to sice adresu rozpozná, ale pak Tě to přesměruje na úplně nesmyslnou adresu. Zvážil bych taky napsání vlastní routy, to poskytuje větší flexibilitu, mimo jiné tam pak budeš moct i nastavovat id podle té domény.

Aurielle
Člen | 1281
+
0
-

Hlavně nepoužívej příznak ONE_WAY, protože pak dojde k automatické kanonizaci na <id>.mujprofil.cz (pokud ji v presenteru nevypneš…)

eudard
Člen | 15
+
+1
-

Díky za reakce: moje řešení, které asi není úplně ok, ale funguje..

$host = $container->httpRequest->url->host;

if ($host!='mujprofil.local') {
    $router[] = new Route('//<id>', array(
        'presenter' => 'Card',
        'action' => 'default',
        'id' => array( Route::FILTER_IN => function($domain) {
                                                return getIdByDomain($domain);
                                                },
        )), Route::ONE_WAY);
} else {
    $router[] = new Route('card/<id>', array(
        'presenter' => 'Card',
        'action' => 'default',
        'id' => NULL
    ));
    $router[] = new Route('<presenter>/<action>[/<id>]', 'Homepage:default');
}

Tím pádem je stejný profil dostupný z adresy
mujprofil.local/card/frantiskovo-id
a taky z adresy
frantisek.cz

jak teď tedy zabezpečím, aby mujprofil.local/card/frantiskovo-id vždycky směrovala na frantisek.local ?

Panda
Člen | 569
+
0
-

Viz předchozí dva příspěvky, nová routa nesmí být ONE_WAY a musí mít nastavený FILTER_OUT pro zpětný překlad. Jako ošklivé self-promo doporučím svojí přednášku z poslední soboty o routování, kde jsem něco podobného řešil. :-)