SimpleSeoRouter

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
Jan Tvrdík
Nette guru | 2595
+
0
-

Jak jsem již psal, tak při používání pěkných URL nerad používám třídu Route, protože presenter pak dostane např. řetězec moje-stránka místo např. čísla 7 (představující ID stránky v DB). Proto jsem si pro tyto účely napsal vlastní velmi jednoduchý router.

Zdrojový kód

<?php
/**
 * Jednoduchý SEO-friendly router
 * ==============================
 *
 * @license     New BSD license
 * @copyright   Copyright (c) 2009 Jan Tvrdík
 * @author      Jan Tvrdík (http://merxes.cz)
 */

/**
 * Jednoduchý SEO router
 *
 * @author      Jan Tvrdík (http://merxes.cz)
 */
abstract class SimpleSeoRouter implements IRouter
{
	/** @var     string      Řetězec vkládaný před před $this->getPath() */
	protected $pathPrefix;

	/** @var     string      Jméno cílového presenteru */
	protected $presenter;

	/** @var     string      Jméno cílové akce */
	protected $action;

	/** @var     string      Jméno parametru předeného presenteru */
	protected $identifierName = 'id';

	/**
	 * Konstruktor
	 *
	 * @param    string      Řetězec vkládaný před před $this->getPath()
	 * @param    string      Jméno cílového presenteru
	 * @param    string      Jméno cílové akce
	 */
	public function __construct($pathPrefix, $presenter, $action)
	{
		$this->pathPrefix = $pathPrefix;
		$this->presenter = $presenter;
		$this->action = $action;
	}

	/**
	 * Zkusí přeložit http požadavek na PresenterRequest
	 *
	 * @param    IHttpRequest
	 * @return   PresenterRequest|NULL
	 */
	public function match(IHttpRequest $httpRequest)
	{
		$path = $httpRequest->getUri()->relativeUri;

		if (!preg_match('#^' . preg_quote($this->pathPrefix, '#') .  '(.+)$#', $path, $matches)) {
			return NULL;
		}

		$url = & $matches[1];

		$id = $this->getId($url);

		if ($id === NULL) {
			return NULL;
		}

		$params = array();
		$params += $httpRequest->getQuery();
		$params['action'] = $this->action;
		$params[$this->identifierName] = $id;

		return new PresenterRequest(
			$this->presenter,
			$httpRequest->getMethod(),
			$params,
			$httpRequest->getPost(),
			$httpRequest->getFiles(),
			array('secured' => $httpRequest->isSecured())
		);
	}

	/**
	 * Zkusí vygenerovat URL pro daný PresenterRequest
	 *
	 * @param    PresenterRequest
	 * @param    IHttpRequest
	 * @return   string|NULL
	 */
	public function constructUrl(PresenterRequest $request, IHttpRequest $context)
	{
		if ($request->getPresenterName() !== $this->presenter) {
			return NULL;
		}

		$params = $request->getParams();

		if ($params['action'] !== $this->action) {
			return NULL;
		}

		if (!isset($params[$this->identifierName])) {
			return NULL;
		}

		$path = $this->getPath($params[$this->identifierName]);

		if ($path === NULL) {
			return NULL;
		}

		unset($params['action']);
		unset($params[$this->identifierName]);

		$uri = new UriScript($context->getUri()->scheme . '://' . $context->getUri()->authority . $context->getUri()->basePath);
		$uri->path .= $this->pathPrefix . $path;
		$uri->query = http_build_query($params, '', '&');

		return $uri->getAbsoluteUri();
	}

	/**
	 * Vrátí identifikátor podle fragmentu URL
	 *
	 * @param    string     Fragment URL
	 * @return   mixed|NULL
	 */
	abstract protected function getId($url);

	/**
	 * Vrátí fragment URL podle identifikátoru
	 *
	 * @param    mixed      Identifikátor
	 * @return   string     Fragment URL
	 */
	abstract protected function getPath($id);
}

Příklad použití

Struktura tabulky galleries
Sloupec Typ Nulový Výchozí
id int(3) Ano NULL
name varchar(100) Ano  
description varchar(1000) Ano NULL
url varchar(100) Ano  
Příklad routeru
class GalleriesRouter extends SimpleSeoRouter
{
	protected function getId($url)
	{
		$query = dibi::query('
			SELECT [galleries].[id]
			FROM [galleries]
			WHERE [url] = %s', $url
		);

		if ($query->rowCount() === 0) {
			return NULL;
		}

		return $query->fetchSingle();
	}

	protected function getPath($id)
	{
		$query = dibi::query('
			SELECT [galleries].[url]
			FROM [galleries]
			WHERE [galleries].[id] = %i', $id
		);

		if ($query->rowCount() === 0) {
			return NULL;
		}

		return $query->fetchSingle();
	}
}
Registrace v bootstrapu
$router[] = new GalleriesRouter('fotogalerie/', 'Front:Galleries', 'view');

Těším se na případnou kritiku a někdy příště se možná podíváme na další příklad routeru.

Editoval Jan Tvrdík (19. 5. 2009 16:35)

Honza Marek
Člen | 1664
+
0
-

Ono se to musí kouknout při každém generování odkazu do databáze, jestli tomu dobře rozumim. Zajímalo by mě, jestli je to poznat na rychlosti nebo ne. Jinak se mi to hodně líbí a ty abstraktní metody se dají koneckonců naimplementovat jinak.

jasir
Člen | 746
+
0
-

Honza M. napsal(a):

Ono se to musí kouknout při každém generování odkazu do databáze, jestli tomu dobře rozumim. Zajímalo by mě, jestli je to poznat na rychlosti nebo ne. Jinak se mi to hodně líbí a ty abstraktní metody se dají koneckonců naimplementovat jinak.

Jo, vypadá to moc hezky. Jinak bych řekl, že je to adept na caching :)

Honza Marek
Člen | 1664
+
0
-

Já tohle řešil tak, že jsem na začátku načetl všechny stránky a to hodil do pole.

Jan Tvrdík
Nette guru | 2595
+
0
-

ad Caching: čekal jsem, že se někdo zeptá :) Záleží na počtu url adres, které se musí na běžné stránce vygenerovat. Pokud je jich jen pár, tak nemá cachování smysl, protože ty dotazy jsou vysloveně ukázkou vysokorychlostních dotazů.

Pokud by se však generoval na jedné stránce větší množství url adres, tak se cache určitě vyplatí.

Osobně jsem zatím jednoúrovňový router použil jenom v takových situacích, že cachování nemělo smysl. U víceúrovňového routeru jsem se ale cachování nevyhnul.

Jan Tvrdík
Nette guru | 2595
+
0
-

Jsem první, komu právě došlu, že ten router se dá použít i pro víceúrovňovou strukturu?

Honza Marek
Člen | 1664
+
0
-

Ne, ale nechtělo se mi kontrolovat, jestli to akceptuje lomítka :-)

Honza Marek
Člen | 1664
+
0
-

Mám ještě dva nápady.

  1. Myslím, že by dobré umožnit jinou action než výchozí (adresy /clanky/nazev-clanku?action=edit).

Pak ještě jeden nápad, který možná umožní umazat Simple z názvu :-D

  1. Určitě by se šikla jazyková proměnná, třeba ještě s nastavením defaultního jazyku (adresy /en/article a /nazev-clanku zároveň). Bez toho defaultního jazyka by to taky mohlo být jednoduché.
Jakub Šulák
Člen | 222
+
0
-

Vypadá to skvěle, ale nějak se mi nedaří to implementovat.
Musel jsem to trochu upravit, ale:

<?php
// bootstrap.php
$this->router[] = new CategoriesRouter('katalog/', 'Search', 'default', $this->defaultLanguage);
$this->router[] = new Route('katalog',array(
       'presenter' => 'Search',
       'action' => 'default'
));
// poznamka:
CategoriesRouter extends Simplerouter
//---
?>

Ten druhý router je tam pro případ, kdy to bude voláno bez parametru (http://www.neco.cz/katalog/).

Když ale zadám www.neco.cz/…y-text-v-db/ tak se sice zavolá správný router, dokonce to vrátí objekt PresenterRequest, ale následně dojde k přesměrování na http://localhost/katalog?…[category]=5.

Parametr lang je jazyk a je ošetřen tak, že se předává v kontruktoru a pak v match se předá jako parametr.
Parametr limiter je pole, ve kterém mohu předávat různá omezení na výběr produktů. $limiter[‚category‘]=5 je omezení na product->id_kategorie=5.

Pole předávám snad také dobře, upravil jsem fnc getId(url) na konci:

<?php
 return array('category'=>$query->fetchSingle());
?>

Můžete mně někdo prosím nakopnout, proč mi to dělá to přesměrování?
Routování jsem ještě s nette neřešil, tak jsem nějak mimo.

díky

Honza Marek
Člen | 1664
+
0
-

Můžete mně někdo prosím nakopnout, proč mi to dělá to přesměrování?

Když router zpracuje url, tak se ji aplikace pokusí znovu vygenerovat, aby docházelo k přesměrování na jednu variantu adresy.

PetrP
Člen | 587
+
0
-

Můžete mně někdo prosím nakopnout, proč mi to dělá to přesměrování?

Nahoď si RoutingDebugger třeba z něho budeš chytřejší.

Musel jsem to trochu upravit, ale:

A hod někam tu upravenou verzi.

EDIT: co je $this v bootstrapu?

Editoval PetrP (19. 5. 2009 13:51)

PetrP
Člen | 587
+
0
-

Jakub Šulák napsal(a):

Vypadá to skvěle, ale nějak se mi nedaří to implementovat.

Když jsem si to zjednodušil:

require_once dirname(__FILE__).'/0.9.php';
Debug::enable();
Debug::enableProfiler();
$application = Environment::getApplication();
$router = $application->getRouter();
abstract class SimpleSeoRouter implements IRouter
...


class CategoriesRouter extends SimpleSeoRouter
{
        protected function getId($url)
        {
                //return $url=='name'?5:NULL;
                return $url=='name'?array('category'=>'5'):NULL;
        }

        protected function getPath($id)
        {
                return $id==5?'name':NULL;
        }
}

$router[] = new CategoriesRouter('katalog/', 'Default', 'default', 'cz');
$router[] = new Route('katalog',array(
       'presenter' => 'Default',
       'action' => 'default',
));


class DefaultPresenter extends Presenter {

	function renderDefault($id)
	{
		Debug::dump($id);
		$this->terminate();
	}
}





$application->run();

Tak to mě adresa http://localhost/Nette-test/katalog/name
přesměrovává na
http://localhost/Nette-test/katalog?id%5Bcategory%5D=5
Když odstraním toto:
return $url=='name'?array('category'=>'5'):NULL;
a nahradím to jen za return $url=='name'?5:NULL; Tak vše funguje zprávně.

Takže se nemůže vracet pole. (Proč ho vlastně potřebuješ vracet?)

Editoval PetrP (19. 5. 2009 14:15)

Jan Tvrdík
Nette guru | 2595
+
0
-

WTF? Co to s mým routerem zkoušíte za hokusy pokusy? :D Čekal jsem, že se spíš dozvím, co zlepšit a ne, že se v něm někdo pohrabal a přestalo mu to fungovat.

Každopádně by to pole klidně vracet mohlo, ale muselo by ho to také detekovat (úpravou jste způsobili nekonzistenci routeru). Tohle by mělo fungovat:

class CategoriesRouter extends SimpleSeoRouter // Předpokládá můj (doufám) funkční SimpleSeoRouter
{
        protected function getId($url)
        {
                return $url == 'name' ? array('category'=>'5') : NULL;
        }

        protected function getPath($id)
        {
                return $id == array('category'=>'5') ? 'name' : NULL;
        }
}
Jan Tvrdík
Nette guru | 2595
+
0
-

Honza M. napsal(a):

  1. Myslím, že by dobré umožnit jinou action než výchozí (adresy /clanky/nazev-clanku?action=edit).

Dobrý nápad. Hotovo.

<?php
/**
 * Jednoduchý SEO-friendly router
 * ==============================
 *
 * @license     New BSD license
 * @copyright   Copyright (c) 2009 Jan Tvrdík
 * @author      Jan Tvrdík (http://merxes.cz)
 */

/**
 * Jednoduchý SEO router
 *
 * @author      Jan Tvrdík (http://merxes.cz)
 */
abstract class SimpleSeoRouter implements IRouter
{
	/** @var     string      Řetězec vkládaný před před $this->getPath() */
	protected $pathPrefix;

	/** @var     string      Jméno cílového presenteru */
	protected $presenter;

	/** @var     string      Jméno výchozí akce */
	protected $defaultAction;

	/** @var     string      Jméno parametru předeného presenteru */
	protected $identifierName = 'id';

	/** @var     string      Klíč použitý pro akci */
	protected $actionKey = 'action';

	/**
	 * Konstruktor
	 *
	 * @param    string      Řetězec vkládaný před před $this->getPath()
	 * @param    string      Jméno cílového presenteru
	 * @param    string      Jméno cílové akce
	 */
	public function __construct($pathPrefix, $presenter, $defaultAction)
	{
		$this->pathPrefix = $pathPrefix;
		$this->presenter = $presenter;
		$this->defaultAction = $defaultAction;
	}

	/**
	 * Zkusí přeložit http požadavek na PresenterRequest
	 *
	 * @param    IHttpRequest
	 * @return   PresenterRequest|NULL
	 */
	public function match(IHttpRequest $httpRequest)
	{
		$path = $httpRequest->getUri()->relativeUri;

		if (!preg_match('#^' . preg_quote($this->pathPrefix, '#') .  '(.+)$#', $path, $matches)) {
			return NULL;
		}

		$url = & $matches[1];

		$id = $this->getId($url);

		if ($id === NULL) {
			return NULL;
		}

		$params = array();
		$params += $httpRequest->getQuery();


		if (!isset($params[$this->actionKey])) {
			$params['action'] = $this->defaultAction;
		} elseif ($this->actionKey !== 'action') {
			$params['action'] = $params[$this->actionKey];
			unset($params[$this->actionKey]);
		}

		$params[$this->identifierName] = $id;

		return new PresenterRequest(
			$this->presenter,
			$httpRequest->getMethod(),
			$params,
			$httpRequest->getPost(),
			$httpRequest->getFiles(),
			array('secured' => $httpRequest->isSecured())
		);
	}

	/**
	 * Zkusí vygenerovat URL pro daný PresenterRequest
	 *
	 * @param    PresenterRequest
	 * @param    IHttpRequest
	 * @return   string|NULL
	 */
	public function constructUrl(PresenterRequest $request, IHttpRequest $context)
	{
		if ($request->getPresenterName() !== $this->presenter) {
			return NULL;
		}

		$params = $request->getParams();

		if (!isset($params[$this->identifierName])) {
			return NULL;
		}

		$path = $this->getPath($params[$this->identifierName]);

		if ($path === NULL) {
			return NULL;
		}


		if ($params['action'] == $this->defaultAction) {
			unset($params['action']);
		} elseif ($this->actionKey !== 'action') {
			$params[$this->actionKey] = $params['action'];
			unset($params['action']);
		}

		unset($params[$this->identifierName]);

		$uri = new UriScript($context->getUri()->scheme . '://' . $context->getUri()->authority . $context->getUri()->basePath);
		$uri->path .= $this->pathPrefix . $path;
		$uri->query = http_build_query($params, '', '&');

		return $uri->getAbsoluteUri();
	}

	/**
	 * Vrátí identifikátor podle fragmentu URL
	 *
	 * @param    string     Fragment URL
	 * @return   mixed|NULL
	 */
	abstract protected function getId($url);

	/**
	 * Vrátí fragment URL podle identifikátoru
	 *
	 * @param    mixed      Identifikátor
	 * @return   string     Fragment URL
	 */
	abstract protected function getPath($id);
}
  1. Určitě by se šikla jazyková proměnná, třeba ještě s nastavením defaultního jazyku (adresy /en/article a /nazev-clanku zároveň). Bez toho defaultního jazyka by to taky mohlo být jednoduché.

Nechceš tuhle představu nějak rozepsat, než se to rozhodnu napsat? Jak to chceš zkombinovat se současnou proměnnou $pathPrefix? Spíš mě napadá, že máš pravdu s tím, že tenhle požadavek odstraní z názvu to Simple, protože to bude dost možná snažší řešit jako abstract class SeoRouter extends Route.

PetrP
Člen | 587
+
0
-

Jan Tvrdík napsal(a):

WTF? Co to s mým routerem zkoušíte za hokusy pokusy? :D Čekal jsem, že se spíš dozvím, co zlepšit a ne, že se v něm někdo pohrabal a přestalo mu to fungovat.

Tak já zkoušel to co zkoušel Jakub Šulák ;]

Každopádně by to pole klidně vracet mohlo, ale muselo by ho to také detekovat (úpravou jste způsobili nekonzistenci routeru). Tohle by mělo fungovat:

Tak v takovéhle formě by vracení pole smysl nemělo, jedině kdyby se jednotlivé položky přidávali jako params (ale nenapadá mě smyslulpné využití ;])

PetrP
Člen | 587
+
0
-

Spíš mam takovej dotaz co to vylepšuje nad použitím překladoveho slovníku?

Route::addStyle('#id');
Route::setStyleProperty('#id', Route::FILTER_IN, 'getId'); // to same co mas v GalleriesRouter
Route::setStyleProperty('#id', Route::FILTER_OUT, 'getPath');

$router[] = new Route('fotogalerie/<id #id>',array(
       'presenter' => 'Front:Galleries',
       'action' => 'view',
));

To totiž dává daleko větší možnosti, možná jsem ale SimpleSeoRouter nepochopil ;]

Jan Tvrdík
Nette guru | 2595
+
0
-

PetrP napsal(a):

Spíš mam takovej dotaz co to vylepšuje nad použitím překladoveho slovníku?

Přesně tohle jsem tady napsal v příspěvku, který jsem smazal, protože jsem si uvědomil, že to nefunguje tak dobře, jak se mi původně zdálo.

Jediný (!) rozdíl, který tam totiž je, je velmi klíčový – pokud metoda getId v SimpleSeoRouter vrátí NULL, vrátí router NULL. Pokud ale funkce v překladovém slovníku vrátí NULL, tak Route NULL nevrátí.

Přemýšlel jsem nad tím, jak to třídu Route naučit a zatím jsem skončil u představy založené na něčem jako PATTERN_CALLBACK.

PetrP
Člen | 587
+
0
-

Hmmm jen takovým jednoduchým zásahem na řádku 207 to vrací NULL

if (($x = call_user_func($meta[self::FILTER_IN], (string) $params[$name]))===NULL)
	return NULL;
$params[$name] = $x;

To samé možná bude potřeba i u FILTER_OUT (ted mi to ale vraci url správně; mozná tam bude ještě nějaká záludnost).
Asi to neni úplně ideální ;] možná to bude mít nějaké skrýté vlastnosti.

Takže když použiju toto:

function getId($url){ return $url=='name'?5:NULL;}
function getPath($id){ return $id==5?'name':NULL;}
function getId2($url){ return $url=='xxx'?4:NULL;}
function getPath2($id){ return $id==4?'xxx':NULL;}
Route::addStyle('#id');
Route::setStyleProperty('#id', Route::FILTER_IN, 'getId');
Route::setStyleProperty('#id', Route::FILTER_OUT, 'getPath');
Route::addStyle('#id2');
Route::setStyleProperty('#id2', Route::FILTER_IN, 'getId2');
Route::setStyleProperty('#id2', Route::FILTER_OUT, 'getPath2');

$router[] = new Route('katalog/<id #id>',array(
       'presenter' => 'Default',
       'action' => 'default',
));

$router[] = new Route('katalog/<id #id2>',array(
       'presenter' => 'Default',
       'action' => 'default',
));

class DefaultPresenter extends Presenter {

	function renderDefault($id)
	{
		Debug::dump($this->link('default',array('id'=>5)));
		Debug::dump($this->link('default',array('id'=>4)));
		Debug::dump($id);
		$this->terminate();
	}
}

Na http://localhost/Nette-test/katalog/xxx vrací

string(24) "/Nette-test/katalog/name"
string(23) "/Nette-test/katalog/xxx"
int(4)

Na http://localhost/Nette-test/katalog/name

string(24) "/Nette-test/katalog/name"
string(23) "/Nette-test/katalog/xxx"
int(5)

Je to očekávané chováni?

Editoval PetrP (19. 5. 2009 18:48)

Jan Tvrdík
Nette guru | 2595
+
0
-

Ano, toto bude (pravděpodobně) fungovat identicky, jako SimpleSeoRouter, ale bohužel zásahy tohoto typu nejsou ideálním řešením :)

PetrP
Člen | 587
+
0
-

Jan Tvrdík napsal(a):

Ano, toto bude (pravděpodobně) fungovat identicky, jako SimpleSeoRouter, ale bohužel zásahy tohoto typu nejsou ideálním řešením :)

No identicky to nefunguje protože můzu mít více parametrů v jedné routě ze slovníkem.
Jakou konkrétně nevýhodu to má? Možná jsem už moc unavenej ale nic moc nevydím, nebo se slovník používá k něčemu při čem by to vadilo?

Jan Tvrdík
Nette guru | 2595
+
0
-

Je třeba si uvědomit, že třída Route a SimpleSeoRouter mají zcela jiný účel. Route je třída pro obecné routování kdečeho, SimpleSeoRouter řeší velmi specifickou situaci, kterou třída Route řešit neumí (přímá editace [ještě ke všemu nekompatibilní] zdrojového kódu route.php není řešením).

Ostatní věci vyplývají ze specifičnosti SimpleSeoRouteru. Jako každá věc na světě, která je specializovaná na určitou činnost, bude vždy lepší (!) než obecné řešení v případě, že řeší přesně to, co řešit potřebuješ. Pokud potřebuješ řešit něco jiného, než SimpleSeoRouter řeší, pak nemá smysl, aby jsi ho používal.

I kdyby se třída Route naučil zpracovávat PATTERN_CALLBACK, tak pokud budeš potřebovat řešit to, co SimpleSeoRouter řeší, tak z obecných principů plyne, že třída Route nikdy nemůže (!) být na danou věc lepší než SimpleSeoRouter. Na druhou stranu pokud by třída Route uměla zpracovávat PATTERN_CALLBACK, tak by třída SimpleSeoRouter pravděpodobně nikdy nevznikla.

PetrP
Člen | 587
+
0
-

Pěkné. A můžeš mi prozradit ty konkrétní nekompability? Předpokládám že je znáš když o nich píšeš.

Jan Tvrdík
Nette guru | 2595
+
0
-

Předtím, když nějaký filterIn vrátil NULL, tak router nevrátil NULL. Pokud má někdo router, který spoléhá na stávající chování, tak mu přestane fungovat. Mnohem víc mi ale vadí, že by mi v kontextu třídy Route přišlo takové chování nelogické.

PetrP
Člen | 587
+
0
-

Pro to by možná mohl být nějaký příznak při nastavení setStyleProperty, připadně existovat jiný druh filtru. Nerozumim přesně proč by podobné chování mělo být nelogické, jen je to nepatrné rozšíření stávajících překladových slovníků (i ty ti připadají nelogické?). Vyřešila by se s tím poslední věc co routy neumí (původně jsem myslel že s tím byl slovník vyroben; ninejší chování pokládám spíš za chybu). A bylo by to mnohem použitelnější než SimpleSeoRouter (ze vší úctou).

David Grudl
Nette Core | 8218
+
0
-

Můžete zkusit ověřit, jestli by pomohla tato úprava v Route.php (od řádku 208)

				} elseif (isset($meta[self::FILTER_IN])) { // applyies filterIn only to scalar parameters
					$params[$name] = call_user_func($meta[self::FILTER_IN], (string) $params[$name]);
					if ($params[$name] === NULL && isset($meta['fixity']) && $meta['fixity'] === self::CONSTANT) {
						return NULL;
					}
				}
Jan Tvrdík
Nette guru | 2595
+
0
-

David Grudl napsal(a):

Můžete zkusit ověřit, jestli by pomohla tato úprava v Route.php (od řádku 208)

Neprojde to podmínkou isset($meta['fixity']). Upřímně ani netuším, k čemu má $meta['fixity'] sloužit.

PetrP
Člen | 587
+
0
-

Tak fixity může nabývat 4 stavů Route::OPTIONAL, Route::PATH_OPTIONAL, Route::CONSTANT, NULL

NULL znamená podle mě povinný protože třeba:

$router[] = new Route('katalog/<id>',array(
));

je fixity NULL

Route::PATH_OPTIONAL je nepovinný:

$router[] = new Route('katalog/<id>',array(
       'id' => NULL,
));

Route::CONSTANT je když není uvedena v masce, ale má defaultní neměnej parametr

$router[] = new Route('katalog',array(
       'id' => null,
));

Route::OPTIONAL je když je parametr v query a ma defaultni hodnotu

$router[] = new Route('katalog ? <id>',array(
       'id' => null,
));

Proto nerozumím proč je tam $meta['fixity'] === self::CONSTANT protože to se možnost filtrem zastavit match dá použít jen na hotnoty které nejsou v url ;] a nemyslím si ze by někdo na to používal filtry.

Takže asi navrhuju změnit podmínku na

if ($params[$name] === NULL && !isset($meta['fixity'])) {

tedy že by se to dalo zastavit jen na povinné parametry, bez defaultni hodnoty.

David Grudl
Nette Core | 8218
+
0
-

Díky za shrnutí významu fixity, když něco dělám po delší době s třídou Route, tak nad tím vždycky dumám a tohle se mi bude hodit ;) Což byl ostatně i tento případ, správná je tva formuluace s !isset($meta['fixity']).

Přidávám to do Route.

Ještě si říkám, že by se možná mohly výsledky z FILTER_OUT kešovat.

pmg
Člen | 372
+
0
-

Také jsem chtěl poděkovat za užitečný průzkum. (David měl zase vnuknutí, když to psal.)

PetrP
Člen | 587
+
0
-

David Grudl napsal(a):

Přidávám to do Route.

Díky moc.

Ještě si říkám, že by se možná mohly výsledky z FILTER_OUT kešovat.

Jen FILTER_OUT tedy při generování adress? a jestli v rámci běhu scriptu tak jo. (dlouhodobější cachování at si každý napíše a invaliduje dle uvážení)

David Grudl
Nette Core | 8218
+
0
-

Chtěl jsem se zeptat, jak je to aktuálně se SimpleSeoRouter – je svou funkcionalitou nahraditelný pomocí Route, nebo naopak by bylo vhodné ho zařadit do extras?

Jan Tvrdík
Nette guru | 2595
+
0
-

V praxi jsem ho ještě třídou Route nahradit nezkoušel, ale mělo by to bez problémů fungovat. Teď už má SimpleSeoRouter spíš smysl jako jeden z příkladů, jak může vypadat vlastní router.

Jan Jakeš
Člen | 177
+
0
-

Zkoušel jsem, jde bez prolémů nahradit Route s využitím Route::setStyleProperty().

Editoval Juan (29. 9. 2009 15:39)