Url, Routy a filtry

13. 12. 2015

Velké skupině lidí stále nemusí být z dokumentace úplně pochopitelné, jak na poměrně jednoduchou věc jako jsou "cool" url.

Tedy, pro začátek zničíme statické volání továrničky na router (RouterFactory) a router budeme vytvářet přes její instanci:

services:
    - App\RouterFactory
    router: @App\RouterFactory::createRouter

A hned i ukázku RouterFactory:

namespace App;

use Nette;
use Nette\Application\Routers\RouteList;
use Nette\Application\Routers\Route;


class RouterFactory
{

    private $urls = [
        'hello-kitty-hrnecek' => [
            'presenter' => 'Products',
            'action' => 'detail',
            'id' => '1010',
        ],
        'hello-kitty-propiska' => [
            'presenter' => 'Products',
            'action' => 'detail',
            'id' => '1234',
        ],
    ];


    /**
     * @return Nette\Application\IRouter
     */
    public function createRouter()
    {
        $router = new RouteList;

        $router[] = new Route('[<url [a-z-0-9\/]+?>]', [
            NULL => [
                Route::FILTER_IN => [$this, 'urlIn'],
                Route::FILTER_OUT => [$this, 'urlOut']
            ]
        ]);

        return $router;
    }


    public function urlIn($params)
    {
        $url = trim($params['url'], '/');

        if (isset($this->urls[$url])) {
            return $this->urls[$url];
        }

        return NULL;
    }


    public function urlOut($params)
    {
        foreach ($this->urls as $url => $url_params) {
            if ($params == $url_params) {
                return ['url' => $url];
            }
        }

        return NULL;
    }

}

Co to dělá? V poslední době už je v dokumentaci zmíněna sekce "globální filtry". Znamená to, že pokud takové filtry vytvoříme (jako v příkladu výše), dostaneme ve filtru _IN pole s url, přičemž musíme vrátil pole minimálně s prvky presenter a action a ve filtru _OUT dostaneme alespoň presenter a action a vracíme url - v poli. Zkuste si dumpnout argumenty funkcí urlIn a urlOut a pochopíte snad lépe.

Dále je třeba brát na vědomí několik věci:

1, Seznam url a jejích parametrů (tedy obsah property ::$urls) je vhodné vést v nějakém persistentním úložišti a opět ho nějak cachovat.

2, Opatrně na restrikci query (a jiných) parametrů, které mohou být smazány v metodě urlOut - Každý presenter, pokud má zděděnou property $autoCanonalize == TRUE, se bude pokoušet při každém requestu zpětně vyrábět z routerem vrácených parametrů url, aby případně přesměroval na kanonickou url. V ten moment se mohou některé query parametry (nebo i pojmenované parametry) ztratit při redirectu (například parametr do, zajišťující funkčnost signálů, nebo fid, který používají flashMessages).

3, Pokud znáte (například) staré existují url, ze kterých budete provádět přesměrování na nové, je pro přehlednost lepší navěsit listener na událost Nette\Application\Application::$onError, než vyrábět routery ze starých url a pak je cpát na nějaké "slunné" místo v aplikaci. Pokud vám skončí aplikace neexistující stránkou, spustí se váš error listener a stavový kód můžete ověřit v argumentu vašeho onError listeneru: if (404 === $exception->getCode()) {, zkus najít redirect na novou url pomocí staré. Kde vezmu starou url? Do listeneru si předám http request.


Přidat komentář

Tento web používá k poskytování služeb a analýze návštěvnosti soubory cookie. Používáním tohoto webu s tím souhlasíte. V pořádku Další informace