Δημιουργία συνδέσμων URL

Η δημιουργία συνδέσμων στη Nette είναι τόσο εύκολη όσο το να δείξετε με το δάχτυλο. Απλά δείξτε και το πλαίσιο θα κάνει όλη τη δουλειά για εσάς. Θα σας δείξουμε:

  • πώς να δημιουργείτε συνδέσμους σε πρότυπα και αλλού
  • πώς να διακρίνετε έναν σύνδεσμο στην τρέχουσα σελίδα
  • τι γίνεται με τους άκυρους συνδέσμους

Χάρη στην αμφίδρομη δρομολόγηση, δεν θα χρειαστεί ποτέ να κωδικοποιήσετε σκληρά τις διευθύνσεις URL της εφαρμογής στα πρότυπα ή στον κώδικα, οι οποίες μπορεί να αλλάξουν αργότερα ή να είναι περίπλοκες στη σύνταξη. Απλώς καθορίστε τον παρουσιαστή και την ενέργεια στο σύνδεσμο, περάστε τυχόν παραμέτρους και το πλαίσιο θα δημιουργήσει μόνο του τη διεύθυνση URL. Στην πραγματικότητα, μοιάζει πολύ με την κλήση μιας συνάρτησης. Θα σας αρέσει.

Στο πρότυπο παρουσιαστή

Τις περισσότερες φορές δημιουργούμε συνδέσμους σε πρότυπα και ένας μεγάλος βοηθός είναι το χαρακτηριστικό n:href:

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

Σημειώστε, ότι αντί για το χαρακτηριστικό HTML href χρησιμοποιήσαμε το n:attribute n:href. Η τιμή του δεν είναι ένα URL, όπως έχετε συνηθίσει με το χαρακτηριστικό href, αλλά το όνομα του παρουσιαστή και της ενέργειας.

Το κλικ σε έναν σύνδεσμο είναι, απλά ειπωμένο, κάτι σαν την κλήση μιας μεθόδου ProductPresenter::renderShow(). Και αν αυτή έχει παραμέτρους στην υπογραφή της, μπορούμε να την καλέσουμε με ορίσματα:

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

Είναι επίσης δυνατό να περάσουμε ονομαστικές παραμέτρους. Ο ακόλουθος σύνδεσμος περνάει την παράμετρο lang με την τιμή en:

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

Εάν η μέθοδος ProductPresenter::renderShow() δεν έχει στην υπογραφή της την $lang, μπορεί να ανακτήσει την τιμή της παραμέτρου χρησιμοποιώντας την $lang = $this->getParameter('lang') ή από την ιδιότητα.

Εάν οι παράμετροι είναι αποθηκευμένες σε πίνακα, μπορούν να επεκταθούν με τον τελεστή ...(expand) στο Latte 2.x):

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

Οι λεγόμενες μόνιμες παράμετροι περνούν επίσης αυτόματα στους συνδέσμους.

Το χαρακτηριστικό n:href είναι πολύ χρήσιμο για τις ετικέτες HTML <a>. Αν θέλουμε να εκτυπώσουμε τον σύνδεσμο αλλού, για παράδειγμα στο κείμενο, χρησιμοποιούμε το {link}:

URL is: {link Home:default}

Στον κώδικα

Η μέθοδος link() χρησιμοποιείται για τη δημιουργία ενός συνδέσμου στον παρουσιαστή:

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

Οι παράμετροι μπορούν επίσης να μεταβιβαστούν ως πίνακας όπου μπορούν επίσης να καθοριστούν ονομαστικές παράμετροι:

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

Οι σύνδεσμοι μπορούν να δημιουργηθούν και χωρίς παρουσιαστή, χρησιμοποιώντας το LinkGenerator και τη μέθοδο link().

Εάν ο στόχος του συνδέσμου είναι παρουσιαστής και δράση, έχει την εξής σύνταξη:

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

Η μορφή υποστηρίζεται από όλες τις ετικέτες Latte και όλες τις μεθόδους παρουσιαστή που λειτουργούν με συνδέσμους, δηλαδή n:href, {link}, {plink}, link(), lazyLink(), isLinkCurrent(), redirect(), redirectPermanent(), forward(), canonicalize() και επίσης LinkGenerator. Έτσι, ακόμη και αν στα παραδείγματα χρησιμοποιείται η n:href, θα μπορούσε να υπάρχει οποιαδήποτε από τις συναρτήσεις.

Η βασική μορφή είναι επομένως Presenter:action:

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

Αν συνδεθούμε με τη δράση του τρέχοντος παρουσιαστή, μπορούμε να παραλείψουμε το όνομά του:

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

Αν η ενέργεια είναι default, μπορούμε να την παραλείψουμε, αλλά η άνω και κάτω τελεία πρέπει να παραμείνει:

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

Οι σύνδεσμοι μπορούν επίσης να παραπέμπουν σε άλλες ενότητες. Εδώ, οι σύνδεσμοι διακρίνονται σε σχετικούς με τις υποενότητες ή απόλυτους. Η αρχή είναι ανάλογη με τις διαδρομές δίσκου, μόνο που αντί για κάθετους υπάρχουν άνω και κάτω τελεία. Ας υποθέσουμε ότι ο πραγματικός παρουσιαστής είναι μέρος της ενότητας Front, τότε θα γράψουμε:

<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>

Μια ειδική περίπτωση είναι η σύνδεση με τον εαυτό της. Εδώ θα γράψουμε this ως στόχο.

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

Μπορούμε να συνδεθούμε σε ένα συγκεκριμένο τμήμα της σελίδας HTML μέσω ενός λεγόμενου αποσπάσματος μετά το σύμβολο κατακερματισμού #:

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

Απόλυτες διαδρομές

Οι σύνδεσμοι που δημιουργούνται από το link() ή το n:href είναι πάντα απόλυτες διαδρομές (δηλ. ξεκινούν με /), αλλά όχι απόλυτες διευθύνσεις URL με πρωτόκολλο και τομέα όπως https://domain.

Για να δημιουργήσετε μια απόλυτη διεύθυνση URL, προσθέστε δύο κάθετους στην αρχή (π.χ. n:href="//Home:"). Ή μπορείτε να αλλάξετε τον παρουσιαστή ώστε να παράγει μόνο απόλυτους συνδέσμους, ρυθμίζοντας το $this->absoluteUrls = true.

Ο στόχος this θα δημιουργήσει έναν σύνδεσμο προς την τρέχουσα σελίδα:

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

Ταυτόχρονα, όλες οι παράμετροι που καθορίζονται στην υπογραφή της action<Action>() ή render<View>() μεθόδου, εάν η action<Action>() δεν έχει οριστεί, μεταφέρονται. Έτσι, αν βρισκόμαστε στις σελίδες Product:show και id:123, ο σύνδεσμος προς την this θα μεταφέρει και αυτή την παράμετρο.

Φυσικά, είναι δυνατόν να καθορίσετε τις παραμέτρους απευθείας:

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

Η συνάρτηση isLinkCurrent() καθορίζει αν ο στόχος του συνδέσμου είναι ο ίδιος με την τρέχουσα σελίδα. Αυτό μπορεί να χρησιμοποιηθεί, για παράδειγμα, σε ένα πρότυπο για τη διαφοροποίηση των συνδέσμων κ.λπ.

Οι παράμετροι είναι οι ίδιες με αυτές της μεθόδου link(), αλλά είναι επίσης δυνατό να χρησιμοποιηθεί το μπαλαντέρ * αντί για μια συγκεκριμένη ενέργεια, που σημαίνει οποιαδήποτε ενέργεια του παρουσιαστή.

{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>

Μια συντομευμένη μορφή μπορεί να χρησιμοποιηθεί σε συνδυασμό με το n:href σε ένα μόνο στοιχείο:

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

Ο χαρακτήρας μπαλαντέρ * αντικαθιστά μόνο τη δράση του παρουσιαστή, όχι τον ίδιο τον παρουσιαστή.

Για να μάθουμε αν βρισκόμαστε σε μια συγκεκριμένη ενότητα ή υποενότητά της μπορούμε να χρησιμοποιήσουμε τη συνάρτηση isModuleCurrent(moduleName).

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

Ο στόχος του συνδέσμου μπορεί να είναι όχι μόνο ο παρουσιαστής και η ενέργεια, αλλά και το σήμα (καλούν τη μέθοδο handle<Signal>()). Η σύνταξη έχει ως εξής:

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

Το σήμα διακρίνεται επομένως με θαυμαστικό:

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

Μπορείτε επίσης να δημιουργήσετε έναν σύνδεσμο προς το σήμα του υποστοιχείου (ή υπο-υποστοιχείου):

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

Επειδή τα συστατικά είναι ξεχωριστές επαναχρησιμοποιήσιμες μονάδες που δεν πρέπει να έχουν καμία σχέση με τους περιβάλλοντες παρουσιαστές, οι σύνδεσμοι λειτουργούν λίγο διαφορετικά. Το χαρακτηριστικό Latte n:href και η ετικέτα {link} και οι μέθοδοι συστατικών όπως η link() και άλλες θεωρούν πάντα τον στόχο ως το όνομα του σήματος. Επομένως, δεν είναι απαραίτητο να χρησιμοποιείται θαυμαστικό:

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

Αν θέλουμε να συνδέσουμε με παρουσιαστές στο πρότυπο συστατικού, χρησιμοποιούμε την ετικέτα {plink}:

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

ή στον κώδικα

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

Μπορεί να συμβεί να δημιουργήσουμε έναν άκυρο σύνδεσμο – είτε επειδή αναφέρεται σε έναν μη υπάρχοντα παρουσιαστή, είτε επειδή περνάει περισσότερες παραμέτρους από αυτές που λαμβάνει η μέθοδος-στόχος στην υπογραφή της, είτε όταν δεν μπορεί να δημιουργηθεί URL για τη στοχευόμενη ενέργεια. Το τι πρέπει να γίνει με τους άκυρους συνδέσμους καθορίζεται από τη στατική μεταβλητή Presenter::$invalidLinkMode. Μπορεί να έχει μία από αυτές τις τιμές (σταθερές):

  • Presenter::InvalidLinkSilent – σιωπηλή λειτουργία, επιστρέφει το σύμβολο # ως διεύθυνση URL
  • Presenter::InvalidLinkWarning – θα παραχθεί E_USER_WARNING
  • Presenter::InvalidLinkTextual – οπτική προειδοποίηση, το κείμενο σφάλματος εμφανίζεται στο σύνδεσμο
  • Presenter::InvalidLinkException – θα εκπέμπεται η εξαίρεση InvalidLinkException

Η προεπιλεγμένη ρύθμιση σε κατάσταση παραγωγής είναι InvalidLinkWarning και σε κατάσταση ανάπτυξης είναι InvalidLinkWarning | InvalidLinkTextual. Το InvalidLinkWarning δεν τερματίζει το σενάριο στο περιβάλλον παραγωγής, αλλά η προειδοποίηση θα καταγραφεί. Στο περιβάλλον ανάπτυξης, το Tracy θα αναχαιτίσει την προειδοποίηση και θα εμφανίσει την μπλε οθόνη σφάλματος. Εάν έχει οριστεί το InvalidLinkTextual, ο παρουσιαστής και τα στοιχεία επιστρέφουν μήνυμα σφάλματος ως URL που ξεκινά με το #error:. Για να κάνουμε τέτοιους συνδέσμους ορατούς, μπορούμε να προσθέσουμε έναν κανόνα CSS στο φύλλο στυλ μας:

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

Αν δεν θέλουμε να παράγονται προειδοποιήσεις στο περιβάλλον ανάπτυξης, μπορούμε να ενεργοποιήσουμε τη λειτουργία silent invalid link mode στη ρύθμιση παραμέτρων.

application:
	silentLinks: true

LinkGenerator

Πώς να δημιουργήσετε συνδέσμους με τη μέθοδο link() comfort, αλλά χωρίς την παρουσία ενός παρουσιαστή; Γι' αυτό υπάρχει εδώ το Nette\Application\LinkGenerator.

LinkGenerator είναι μια υπηρεσία που μπορείτε να έχετε περάσει μέσω του κατασκευαστή και στη συνέχεια να δημιουργήσετε συνδέσμους χρησιμοποιώντας τη μέθοδό του link().

Υπάρχει μια διαφορά σε σχέση με τους παρουσιαστές. Το LinkGenerator δημιουργεί όλους τους συνδέσμους ως απόλυτες διευθύνσεις URL. Επιπλέον, δεν υπάρχει “τρέχων παρουσιαστής”, οπότε δεν είναι δυνατόν να καθορίσετε μόνο το όνομα της ενέργειας link('default') ή τις σχετικές διαδρομές προς τις ενότητες.

Οι άκυροι σύνδεσμοι πάντα προκαλούν Nette\Application\UI\InvalidLinkException.

έκδοση: 4.0