URL-Links erstellen

Das Erstellen von Links in Nette ist so einfach wie ein Fingerzeig. Zeigen Sie einfach darauf und das Framework erledigt die ganze Arbeit für Sie. Wir werden es zeigen:

  • wie man Links in Vorlagen und anderswo erstellt
  • wie man einen Link von der aktuellen Seite unterscheidet
  • was mit ungültigen Links geschieht

Dank des bidirektionalen Routings müssen Sie die URLs der Anwendung nicht mehr in den Vorlagen oder im Code fest codieren, was sich später ändern oder kompliziert sein kann. Geben Sie einfach den Präsentator und die Aktion im Link an, übergeben Sie beliebige Parameter und das Framework generiert die URL selbst. Tatsächlich ist es dem Aufruf einer Funktion sehr ähnlich. Sie werden es mögen.

In der Präsentatorvorlage

Am häufigsten erstellen wir Links in Vorlagen und ein großer Helfer ist das Attribut n:href:

<a n:href="Product:show">detail</a>

Beachten Sie, dass wir anstelle des HTML-Attributs href das n:attribute n:href verwendet haben. Sein Wert ist keine URL, wie Sie es von dem Attribut href gewohnt sind, sondern der Name des Präsentators und der Aktion.

Ein Klick auf einen Link ist, einfach gesagt, so etwas wie der Aufruf einer Methode ProductPresenter::renderShow(). Und wenn sie Parameter in ihrer Signatur hat, können wir sie mit Argumenten aufrufen:

<a n:href="Product:show $product->id, $product->slug">detail</a>

Es ist auch möglich, benannte Parameter zu übergeben. Der folgende Link übergibt den Parameter lang mit dem Wert en:

<a n:href="Product:show $product->id, lang: en">detail</a>

Wenn die Methode ProductPresenter::renderShow() nicht $lang in ihrer Signatur hat, kann sie den Wert des Parameters über $lang = $this->getParameter('lang') oder über die Eigenschaft abrufen.

Wenn die Parameter in einem Array gespeichert sind, können sie mit dem ... -Operator (oder (expand) -Operator in Latte 2.x) expandiert werden:

{var $args = [$product->id, lang => en]}
<a n:href="Product:show ...$args">detail</a>

Die so genannten persistenten Parameter werden ebenfalls automatisch in den Links übergeben.

Das Attribut n:href ist sehr praktisch für HTML-Tags <a>. Wenn wir den Link an anderer Stelle, zum Beispiel im Text, ausgeben wollen, verwenden wir {link}:

URL is: {link Home:default}

Im Code

Die Methode link() wird verwendet, um einen Link im Presenter zu erstellen:

$url = $this->link('Product:show', $product->id);

Parameter können auch als Array übergeben werden, wobei auch benannte Parameter angegeben werden können:

$url = $this->link('Product:show', [$product->id, 'lang' => 'cs']);

Links können auch ohne Presenter erstellt werden, indem der LinkGenerator und seine Methode link() verwendet werden.

Wenn das Ziel des Links Presenter und Action ist, hat er diese Syntax:

[//] [[[[:]module:]presenter:]action | this] [#fragment]

Das Format wird von allen Latte-Tags und allen Presenter-Methoden unterstützt, die mit Links arbeiten, also n:href, {link}, {plink}, link(), lazyLink(), isLinkCurrent(), redirect(), redirectPermanent(), forward(), canonicalize() und auch LinkGenerator. Also auch wenn n:href in den Beispielen verwendet wird, könnte es jede der Funktionen sein.

Die Grundform ist also Presenter:action:

<a n:href="Home:default">home</a>

Wenn wir auf die Aktion des aktuellen Moderators verweisen, können wir seinen Namen weglassen:

<a n:href="default">home</a>

Wenn die Aktion default lautet, können wir sie weglassen, aber der Doppelpunkt muss bleiben:

<a n:href="Home:">home</a>

Links können auch auf andere Module verweisen. Hier unterscheidet man zwischen relativen und absoluten Links zu den Untermodulen. Das Prinzip ist analog zu Plattenpfaden, nur dass anstelle von Schrägstrichen Doppelpunkte stehen. Nehmen wir an, dass der eigentliche Präsentator Teil des Moduls Front ist, dann schreiben wir:

<a n:href="Shop:Product:show">link to Front:Shop:Product:show</a>
<a n:href=":Admin:Product:show">link to Admin:Product:show</a>

Ein Sonderfall ist die Verknüpfung mit sich selbst. Hier schreiben wir this als Ziel.

<a n:href="this">refresh</a>

Wir können auf einen bestimmten Teil der HTML-Seite über ein so genanntes Fragment nach dem Rautezeichen # verlinken:

<a n:href="Home:#main">link to Home:default and fragment #main</a>

Absolute Pfade

Die von link() oder n:href erzeugten Links sind immer absolute Pfade (d. h. sie beginnen mit /), nicht aber absolute URLs mit Protokoll und Domäne wie https://domain.

Um eine absolute URL zu erzeugen, fügen Sie zwei Schrägstriche am Anfang hinzu (z. B. n:href="//Home:"). Sie können den Präsentator auch so einstellen, dass er nur absolute Links erzeugt, indem Sie $this->absoluteUrls = true einstellen.

Das Ziel this wird einen Link zur aktuellen Seite erstellen:

<a n:href="this">refresh</a>

Gleichzeitig werden alle Parameter, die in der Signatur des Befehls action<Action>() oder render<View>() Methode angegebenen Parameter, wenn die action<Action>() nicht definiert ist, übertragen. Wenn wir uns also auf den Seiten Product:show und id:123 befinden, wird der Link zu this auch diesen Parameter übergeben.

Natürlich ist es auch möglich, die Parameter direkt anzugeben:

<a n:href="this refresh: 1">refresh</a>

Die Funktion isLinkCurrent() ermittelt, ob das Ziel des Links mit der aktuellen Seite identisch ist. Dies kann z. B. in einer Vorlage zur Unterscheidung von Links usw. verwendet werden.

Die Parameter sind die gleichen wie bei der Methode link(), aber es ist auch möglich, den Platzhalter * anstelle einer bestimmten Aktion zu verwenden, d.h. jede Aktion des Präsentators.

{if !isLinkCurrent('Admin:login')}
	<a n:href="Admin:login">Přihlaste se</a>
{/if}

<li n:class="isLinkCurrent('Product:*') ? active">
	<a n:href="Product:">...</a>
</li>

Eine abgekürzte Form kann in Kombination mit n:href in einem einzelnen Element verwendet werden:

<a n:class="isLinkCurrent() ? active" n:href="Product:detail">...</a>

Das Platzhalterzeichen “*” ersetzt nur die Aktion des Präsentators, nicht den Präsentator selbst.

Um herauszufinden, ob wir uns in einem bestimmten Modul oder dessen Untermodul befinden, können wir die Funktion isModuleCurrent(moduleName) verwenden.

<li n:class="isModuleCurrent('MyEshop:Users') ? active">
	<a n:href="Product:">...</a>
</li>

Das Ziel des Links kann nicht nur der Präsentator und die Aktion sein, sondern auch das Signal (sie rufen die Methode handle<Signal>()). Die Syntax lautet wie folgt:

[//] [sub-component:]signal! [#fragment]

Das Signal ist also durch ein Ausrufezeichen gekennzeichnet:

<a n:href="click!">signal</a>

Sie können auch einen Verweis auf das Signal der Unterkomponente (oder Unter-Unterkomponente) erstellen:

<a n:href="componentName:click!">signal</a>

Da Komponenten separate, wiederverwendbare Einheiten sind, die keine Beziehungen zu umgebenden Präsentatoren haben sollten, funktionieren die Links etwas anders. Das Latte-Attribut n:href und das Tag {link} sowie Komponentenmethoden wie link() und andere betrachten immer das Ziel als Signalnamen. Daher ist es nicht notwendig, ein Ausrufezeichen zu verwenden:

<a n:href="click">signal, not an action</a>

Wenn wir auf Präsentatoren in der Komponentenvorlage verlinken wollen, verwenden wir das Tag {plink}:

<a href={plink Home:default}>home</a>

oder im Code

$this->getPresenter()->link('Home:default')

Aliasnamen

Manchmal ist es sinnvoll, einem Presenter:Action-Paar einen leicht zu merkenden Alias zuzuweisen. Zum Beispiel könnten Sie die Homepage Front:Home:default einfach als home oder Admin:Dashboard:default als admin benennen.

Aliasnamen werden in der Konfiguration unter dem Schlüssel application › aliases definiert:

application:
    aliases:
        home: Front:Home:default
        admin: Admin:Dashboard:default
        sign: Front:Sign:in

In Links werden sie mit dem at-Symbol geschrieben, zum Beispiel:

<a n:href="@admin">administration</a>

Sie werden in allen Methoden unterstützt, die mit Links arbeiten, wie redirect() und ähnliche.

Es kann vorkommen, dass wir einen ungültigen Link erstellen – entweder weil er auf einen nicht existierenden Presenter verweist, oder weil er mehr Parameter übergibt, als die Zielmethode in ihrer Signatur erhält, oder wenn es keine generierte URL für die angestrebte Aktion geben kann. Was mit ungültigen Links zu tun ist, wird durch die statische Variable Presenter::$invalidLinkMode bestimmt. Sie kann einen der folgenden Werte (Konstanten) haben:

  • Presenter::InvalidLinkSilent – stiller Modus, gibt das Symbol # als URL zurück
  • Presenter::InvalidLinkWarning – E_USER_WARNING wird erzeugt
  • Presenter::InvalidLinkTextual – visuelle Warnung, der Fehlertext wird im Link angezeigt
  • Presenter::InvalidLinkException – Es wird eine InvalidLinkException ausgelöst

Die Standardeinstellung im Produktionsmodus ist InvalidLinkWarning und im Entwicklungsmodus ist InvalidLinkWarning | InvalidLinkTextual. InvalidLinkWarning beendet das Skript in der Produktionsumgebung nicht, aber die Warnung wird protokolliert. In der Entwicklungsumgebung fängt Tracy die Warnung ab und zeigt den Fehlerbluescreen an. Wenn InvalidLinkTextual gesetzt ist, geben Presenter und Komponenten die Fehlermeldung als URL zurück, die mit #error: beginnt. Um solche Links sichtbar zu machen, können wir eine CSS-Regel zu unserem Stylesheet hinzufügen:

a[href^="#error:"] {
	background: red;
	color: white;
}

Wenn wir nicht wollen, dass in der Entwicklungsumgebung Warnungen ausgegeben werden, können wir in der Konfiguration den Modus “Stiller ungültiger Link” einschalten.

application:
	silentLinks: true

LinkGenerator

Wie erstellt man Links mit der Methode link() comfort, aber ohne die Anwesenheit eines Presenters? Deshalb gibt es hier Nette\Application\LinkGenerator.

LinkGenerator ist ein Dienst, den Sie über den Konstruktor übergeben können und dann Links mit seiner Methode link() erstellen.

Es gibt einen Unterschied zu Presentern. LinkGenerator erstellt alle Links als absolute URLs. Außerdem gibt es keinen “aktuellen Präsentator”, so dass es nicht möglich ist, nur den Namen der Aktion link('default') oder die relativen Pfade zu den Modulen anzugeben.

Ungültige Links führen immer zu Nette\Application\UI\InvalidLinkException.

Version: 4.0