# Zend_Controller_Router_Route

`Zend_Controller_Router_Route` ist die standardmäßige Framework Route. Sie kombiniert einfache Verwendung mit einer flexiblen Routendefinition. Jede Route besteht primär aus URL Übereinstimmungen (von statischen und dynamischen Teilen (Variablen)) und kann mit Standardwerten initialisiert werden wie auch mit variablen Notwendigkeiten.

Angenommen unsere fiktive Anwendung benötigt eine informelle Seite über den Seitenauthor. Es soll möglich sein mit dem Browser auf `http://domain.com/author/martel` zu verweisen um die Informationen über diesen "martel" Typ zu sehen. Und die Route für so eine Funktionalität würde so aussehen:

    $route = new Zend_Controller_Router_Route(
        'author/:username',
        array(
            'controller' => 'profile',
            'action'     => 'userinfo'
        )
    );

    $router->addRoute('user', $route);

Der ersten Parameter im Konstruktor von `Zend_Controller_Router_Route` ist eine Routendefinition die einer URL entspricht. Routendefinitionen bestehen aus statischen und dynamischen Teilen die durch einen Schrägstrich ('/') seperiert sind. Statische Teile sind nur einfacher Text: `author`. Dynamische Teile, Variablen genannt, werden durch einen vorangestellten Doppelpunkt, zum variablen Namen, markiert: `:username`.

## Zeichen verwenden

Die aktuelle Implementation erlaubt die Verwendung von allen Zeichen (außer einem Schrägstrich) als variablen Identifikator, aber es wird dringend empfohlen das nur Zeichen verwendet werden die auch für PHP Veriablen Identifikatoren gültig sind. Zukünftige Implementationen können dieses Verhlaten ändern, was zu versteckten Bugs im eigenen Code führen würde.

Diese Beispielroute wird verglichen wenn der Browser auf `http://domain.com/author/martel` zeigt. In diesem Fall werden alle seine Variablen dem `Zend_Controller_Request` Objekt injiziiert und es kann im `ProfileController` darauf zugegriffen werden. Variablen die von diesem Beispiel zurückgegeben werden können als Array mit den folgenden Schlüssel- und Wertepaaren repräsentiert werden:

    $values = array(
        'username'   => 'martel',
        'controller' => 'profile',
        'action'     => 'userinfo'
    );

Später sollte `Zend_Controller_Dispatcher_Standard` die `userinfoAction()` Methode der eigenen `ProfileController` Klasse aufrufen (im Standardmodul) basierend auf diesen Werten. Dort ist es möglich alle Variablen durch die `Zend_Controller_Action::_getParam()` oder `Zend_Controller_Request::getParam()` Methoden zuzugreifen:

    public function userinfoAction()
    {
        $request = $this->getRequest();
        $username = $request->getParam('username');

        $username = $this->_getParam('username');
    }

Eine Routendefinition kann ein weiteres spezielles Zeichen enthalten - eine Wildcard - dargestellt durch ein '*' Symbol. Es wird verwendet um Parameter genauso wie im standard Modulrouter zu erhalten (var => Wertepaare definiert in der URI). Die folgende Route imitiert mehr oder weniger das Verhalten des Modulrouters:

    $route = new Zend_Controller_Router_Route(
        ':module/:controller/:action/*',
        array('module' => 'default')
    );
    $router->addRoute('default', $route);

## Variable Standards

Jede Variable im Router kann einen Standardwert haben und das ist für was der zweite Parameter des Konstruktors von `Zend_Controller_Router_Route` verwendet wird. Dieser Parameter ist ein Array mit Schlüsseln die Variablennamen repräsentieren und mit Werten als gewünschte Standards:

    $route = new Zend_Controller_Router_Route(
        'archive/:year',
        array('year' => 2006)
    );
    $router->addRoute('archive', $route);

Die obige Route entspricht URLs wie `http://domain.com/archive/2005` und `http://example.com/archive`. Im späteren Fall wird die Variable year einen initialen Standardwert von 2006 haben.

Dieses Beispiel resultiert darin das eine year Variable in das Anfrage Objekt injiziiert wird. Da keine Routinginformation vorhanden ist (es sind keine Controller und Aktionsparameter definiert), wird die Anwendung zum Standardcontroller und der Aktionsmethode (welche beide in `Zend_Controller_Dispatcher_Abstract` definiert sind) weitergeleitet. Um es verwendbarer zu machen muß ein gültiger Controller und eine gültige aktion als Standard für die Route angegeben werden:

    $route = new Zend_Controller_Router_Route(
        'archive/:year',
        array(
            'year'       => 2006,
            'controller' => 'archive',
            'action'     => 'show'
        )
    );
    $router->addRoute('archive', $route);

Diese Route führt dazu das an die Methode `showAction()` der Klasse `ArchiveController` weitergeleitet wird.

## Variable Anforderungen

Man kann einen dritten Parameter dem `Zend_Controller_Router_Route` Konstruktor hinzufügen wo variable Anforderungen gesetzt werden können. Diese werden als Teil eines regulären Ausdrucks definiert:

    $route = new Zend_Controller_Router_Route(
        'archive/:year',
        array(
            'year'       => 2006,
            'controller' => 'archive',
            'action'     => 'show'
        ),
        array('year' => '\d+')
    );
    $router->addRoute('archive', $route);

Mit einer Route die wie oben definiert ist, wird das Routing nur dann stattfinden wenn die year Variable nummerische Daten enthält, z.B. `http://domain.com/archive/2345`. Eine URL wie `http://example.com/archive/test` wird nicht zugeordnet und die Kontrolle wird stattdessen an die nächste Route in der Kette übertragen.

## Übersetzte Segmente

Die Standardroute unterstützt übersetzte Segmente. Um dieses Feature zu verwenden muß zumindest ein Übersetzer (eine Instanz von `Zend_Translate`) auf einem der folgenden Wege definiert werden:

- In die Registry mit dem Schlüssel `Zend_Translate` geben.

- Über die statische Methode `Zend_Controller_Router_Route::setDefaultTranslator()` setzen.

- Als vierten Parameter im Constructor übergeben.

Standardmäßig wird das Gebietsschema verwendet das in der Instanz von `Zend_Translate` verwendet wird. Um es zu überschreiben, kann es (als Instanz von `Zend_Locale` oder einem Gebietsschema-String) auf einem der folgenden Wege gesetzt werden:

- In die Registry mit dem Schlüssel `Zend_Locale` geben.

- Über die statische Methode `Zend_Controller_Router_Route::setDefaultLocale()` setzen.

- Als fünften Parameter im Constructor übergeben.

- Als `@locale` Parameter der assemble Methode übergeben.

Übersetzte Segmente werden in zwei Teile getrennt. Ein fixes Segment dem ein einzelnes @-Zeichen vorangestellt wird, der anhand des aktuellen Gebietsschemas übersetzt wird und auf der Position des Parameters eingefügt wird. Dynamischen Segmenten wird ein `:@` vorangestellt. Beim Zusammenbauen, wird der gegebene Parameter übersetzt und an der Position des Parameters eingefügt. Bei der Überprüfung, wird der übersetzte Parameter von der URL wieder in die Nachrichten ID umgewandelt.

### Nachrichten IDs und eigene Sprachdateien

Normalerweise werden Nachrichten IDs die man in einer seiner Routen verwenden will, bereits in einem View Skript oder irgendwo anders verwendet. Um die komplette Kontrolle über sichere URLs zu haben, sollte man eine eigene Sprachdatei für die Nachrichten haben die in einer Route verwendet werden.

Nachfolgend ist die einfachste Verwendung gezeigt um eine Standardroute für übersetzte Segmente zu Verwenden:

    // Den Übersetzer vorbereiten
    $translator = new Zend_Translate('array', array(), 'en');
    $translator->addTranslation(array('archive' => 'archiv',
                                      'year'    => 'jahr',
                                      'month'   => 'monat',
                                      'index'   => 'uebersicht'),
                                'de');

    // Das aktuelle Gebietsschema für den Übersetzer setzen
    $translator->setLocale('en');

    // Als Standard-Übersetzer für Routen setzen
    Zend_Controller_Router_Route::setDefaultTranslator($translator);

Dieses Beispiel zeigt die Verwendung von statischen Segmenten:

    // Die Route erstellen
    $route = new Zend_Controller_Router_Route(
        '@archive',
        array(
            'controller' => 'archive',
            'action'     => 'index'
        )
    );
    $router->addRoute('archive', $route);

    // Die URL im Standard-Gebietsschema zusammenbauen: archive
    $route->assemble(array());

    // Die URL in Deutsch zusammenbauen: archiv
    $route->assemble(array());

Man kann dynamische Segmente verwenden um eine Modul-Route, so wie die übersetzte Version, zu erstellen:

    // Die Route erstellen
    $route = new Zend_Controller_Router_Route(
        ':@controller/:@action/*',
        array(
            'controller' => 'index',
            'action'     => 'index'
        )
    );
    $router->addRoute('archive', $route);

    // Die URL im Standard-Gebietsschema zusammenbauen: archive/index/foo/bar
    $route->assemble(array('controller' => 'archive', 'foo' => 'bar'));

    // Die URL in Deutsch zusammenbauen: archiv/uebersicht/foo/bar
    $route->assemble(array('controller' => 'archive', 'foo' => 'bar'));

Man kann auch statische und dynamische Segmente mischen:

    // Die Route erstellen
    +$route = new Zend_Controller_Router_Route(
        '@archive/:@mode/:value',
        array(
            'mode'       => 'year'
            'value'      => 2005,
            'controller' => 'archive',
            'action'     => 'show'
        ),
        array('mode'  => '(month|year)'
              'value' => '\d+')
    );
    $router->addRoute('archive', $route);

    // Die URL im Standard-Gebietsschema zusammenbauen: archive/month/5
    $route->assemble(array('mode' => 'month', 'value' => '5'));

    // Die URL in Deutsch zusammenbauen: archiv/monat/5
    $route->assemble(array('mode' => 'month', 'value' => '5', '@locale' => 'de'));