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.
Links zum Presenter
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.
Link zur aktuellen Seite
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>
Links zu Signal
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>
Verknüpfungen in der Komponente
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.
Ungültige Links
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ückPresenter::InvalidLinkWarning
– E_USER_WARNING wird erzeugtPresenter::InvalidLinkTextual
– visuelle Warnung, der Fehlertext wird im Link angezeigtPresenter::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
.