Slug routy pro úvodní stránky jazykových mutací bez slugů

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

Ahoj,
potřeboval bych uzpůsobit router pro generování adres vícejazyčného webu tak, aby obsahovaly pouze slug a jazykovou verzi, ale neobsahovaly slug pro úvodní stránku jazyk. mutací. Zároveň aby odkaz neobsahoval výchozí jazyk locale. Ukázka asi napoví více:

Úvodní stránky jazykových mutací:
Slugy se do odkazu nezahrují.
Výchozí jazyk locale je CS a do odkazu se nezahrnuje.

- www...cz/ - locale = cs, slug = uvod
- www...cz/en/ - locale = en, slug = homepage

Ostatní stránky:
Slugy se do odkazu zahrnují.
Výchozí jazyk locale je CS a do odkazu se nezahrnuje.

- www...cz/mapa-stranek/ - locale = cs, slug = mapa-stranek
- www...cz/en/sitemap/ - locale = cs, slug = sitemap

Mechanismus překladu slugu na modul/presenter/akce mám vyřešený pomocí FILTER_IN a FILTER_OUT, tím se zde netřeba zabývat si myslím.

Následující kód je jasný, funguje ale pouze pro úvodní stránku CS mutace:

$router[] = new Route('[<locale=cs cs|en>/][<slug=uvod>/]', array(...

- www...cz/
- www...cz/mapa-stranek/
- www...cz/en/homepage/ // zde "pouze" odstranit slug
- www...cz/en/sitemap/

Různě jsme nad tím laboroval a tak, ale nemůžu najít tu správnou cestu.
Kdyby jstě měli někdo nějaký nápad, budu vděčný.

CZechBoY
Člen | 3608
+
0
-

Si udelej 2 routy, to je asi nejrychlejsi :-).

flamengo
Člen | 131
+
0
-

@CZechBoY To mě taky napadlo, ale stále dělám něco špatně.

Když si vytvořím nový projekt a udělám pár úprav:

// HomepagePresenter.php
/** @persistent */
public $locale = 'cs';

// RouterFactory.php
$router[] = new Route('[<locale=cs [a-z]{2}>/][<slug=uvod>/]', 'Homepage:default');
$router[] = new Route('[<locale=en [a-z]{2}>/][<slug=homepage>/]', 'Homepage:default');
$router[] = new Route('<presenter>/<action>', 'Homepage:default');

// default.latte
<a href="{link Homepage:default, locale => cs, slug => uvod}">CS</a>
<a href="{link Homepage:default, locale => en, slug => homepage}">EN</a>

Tak mi to generuje odkazy:

http://127.0.0.1/route-test/
http://127.0.0.1/route-test/en/homepage/

Asi nějak mrším ty routy, že? Ale jak? :)

CZechBoY
Člen | 3608
+
0
-

@flamengo Zkus to takhle

// RouterFactory.php
$router[] = new Route('/', [
	Route::PRESENTER_KEY => 'Homepage',
	'action'             => 'default',
	'locale'             => 'cs',
	'slug'               => 'homepage'
]);
$router[] = new Route('[<locale=en [a-z]{2}>/][<slug=homepage>/]', 'Homepage:default');
// $router[] = new Route('<presenter>/<action>', 'Homepage:default'); // je toto nutné?

Editoval CZechBoY (23. 12. 2016 19:40)

flamengo
Člen | 131
+
0
-

@CZechBoY Zkusil jsme přesně co jsi psal a bohužel nefunguje :( Odkazy jsou takto:

http://127.0.0.1/route-test/uvod/
http://127.0.0.1/route-test/
F.Vesely
Člen | 368
+
+1
-

Zkus globalni filtry:

$router[] = new Route('[<locale=cs cs|en>/][<slug>/]',[
	'presenter' => 'Homepage',
	'action' => 'default',
	NULL => [
		Route::FILTER_OUT => function(array $params) {
			if (isset($params['slug']) && in_array($params['slug'], ['uvod', 'homepage'])) {
				unset($params['slug']);
			}
			return $params;
		},
	]
]);

Editoval F.Vesely (23. 12. 2016 23:42)

flamengo
Člen | 131
+
0
-

@F.Vesely Díky, taky mě to napadlo. Vlastně ten router mám řešen přes filtry, takže nakonec bude stačit to tam jen doplnit. Teda doufám, vyzkouším :)

flamengo
Člen | 131
+
+1
-

Takže kdyby to někdo potřeboval nebo se chtěl inspirovat, tak jsem to sesmolil následovně:

/*
www...cz/
www...cz/en/
www...cz/mapa-stranek/
www...cz/en/sitemap/
www...cz/1-detail-polozky/
www...cz/en/1-detail-item/
www...cz/page-2/
www...cz/en/page-2/
www...cz/1-detail-polozky/page-2/
www...cz/en/1-detail-item/page-2/
*/
$homepages = $this->pagesModel->getHomepages();
$locale = '<locale='.$this->langs->getDefaultLang().' '.implode('|', $this->langs->getAvailableLangs()).'>';  // <locale=cs cs|en>

$router[] = new Route('['.$locale.'/][<slug>/][<id \d+>-<slugItm>][page-<page \d+>]', array(
	NULL => array(
		Route::FILTER_IN => function ($params) {  // Dle adresy načítám presenter.
			$page = $this->pagesModel->getPage($params['slug'], $params['locale']);
			if(!$page){
				return NULL;
			}
			$params['presenter'] = $page->module.':'.$page->presenter;
			$params['action'] = isset($params['slugItm']) ? 'detail' : $page->action;  // Detail položky má danou hodnotu action, hodnota se přepíše.
			return $params;
		},
		Route::FILTER_OUT => function ($params) use ($homepages) { // Tvořím URL adresu.
			$locale = isset($params['locale']) ? $params['locale'] : $this->langs->getDefaultLang();  // Úvodní stránka nemá locale.
			if(isset($params['slug']) && $params['slug'] == $homepages[$locale]->slug){
				unset($params['slug']);  // Pro úvodní stránku se odstraní slug.
			}
			if(isset($params['page']) && $params['page'] == 1){
				unset($params['page']);  // Parametr page se pro první stranu odstraní.
			}
			unset($params['module'], $params['presenter'], $params['action']);  // Zůstane locale a slug.
			return $params;
		}
	)
));