Κληρονομικότητα προτύπων και επαναχρησιμοποίηση
Οι μηχανισμοί επαναχρησιμοποίησης προτύπων και κληρονομικότητας είναι εδώ για να ενισχύσουν την παραγωγικότητά σας, επειδή κάθε πρότυπο περιέχει μόνο το μοναδικό του περιεχόμενο και τα επαναλαμβανόμενα στοιχεία και δομές επαναχρησιμοποιούνται. Παρουσιάζουμε τρεις έννοιες: κληρονομικότητα διάταξης, οριζόντια επαναχρησιμοποίηση και κληρονομικότητα μονάδων.
Η έννοια της κληρονομικότητας προτύπων Latte είναι παρόμοια με την κληρονομικότητα κλάσεων της PHP. Ορίζετε ένα πρότυπο γονέα από το οποίο άλλα πρότυπα-παιδιά μπορούν να επεκταθούν και να αντικαταστήσουν τμήματα του προτύπου γονέα. Λειτουργεί εξαιρετικά όταν τα στοιχεία μοιράζονται μια κοινή δομή. Ακούγεται περίπλοκο; Μην ανησυχείτε, δεν είναι.
Κληρονομικότητα διάταξης {layout}
Ας δούμε την κληρονομικότητα προτύπων διάταξης ξεκινώντας με ένα
παράδειγμα. Πρόκειται για ένα πρότυπο γονέα το οποίο θα ονομάσουμε για
παράδειγμα layout.latte
και ορίζει ένα έγγραφο-σκελετό HTML.
Οι ετικέτες {block}
ορίζουν τρία μπλοκ που μπορούν να
συμπληρώσουν τα πρότυπα-παιδιά. Το μόνο που κάνει η ετικέτα μπλοκ είναι
να πει στη μηχανή προτύπων ότι ένα πρότυπο παιδί μπορεί να παρακάμψει
αυτά τα τμήματα του προτύπου ορίζοντας το δικό του μπλοκ με το
ίδιο όνομα.
Ένα υποκατάστατο πρότυπο μπορεί να μοιάζει ως εξής:
Η ετικέτα {layout}
είναι το κλειδί εδώ. Λέει στη μηχανή προτύπων
ότι αυτό το πρότυπο „επεκτείνει“ ένα άλλο πρότυπο. Όταν το Latte
αποδίδει αυτό το πρότυπο, πρώτα εντοπίζει τον γονέα – σε αυτή την
περίπτωση, το layout.latte
.
Σε αυτό το σημείο, η μηχανή προτύπων θα παρατηρήσει τις τρεις
ετικέτες μπλοκ στο layout.latte
και θα αντικαταστήσει αυτά τα μπλοκ
με τα περιεχόμενα του προτύπου-παιδί. Σημειώστε ότι εφόσον το πρότυπο
παιδί δεν όρισε το μπλοκ footer, αντί αυτού χρησιμοποιείται το
περιεχόμενο από το πρότυπο γονέα. Το περιεχόμενο μέσα σε μια ετικέτα
{block}
σε ένα γονικό πρότυπο χρησιμοποιείται πάντα ως εφεδρικό.
Η έξοδος μπορεί να μοιάζει ως εξής:
Σε ένα πρότυπο παιδί, τα μπλοκ μπορούν να βρίσκονται μόνο είτε στο ανώτερο επίπεδο είτε μέσα σε ένα άλλο μπλοκ, δηλ:
Επίσης, ένα μπλοκ θα δημιουργείται πάντα στο ανεξάρτητα από το αν η
συνθήκη που το περιβάλλει {if}
αξιολογείται ως αληθής ή ψευδής. Σε
αντίθεση με ό,τι μπορεί να νομίζετε, αυτό το πρότυπο ορίζει
ένα μπλοκ.
Αν θέλετε η έξοδος μέσα στο μπλοκ να εμφανίζεται υπό συνθήκη, χρησιμοποιήστε αντ' αυτού τα ακόλουθα:
Τα δεδομένα έξω από ένα μπλοκ σε ένα πρότυπο παιδί εκτελούνται πριν
από την απόδοση του προτύπου διάταξης, επομένως μπορείτε να το
χρησιμοποιήσετε για να ορίσετε μεταβλητές όπως το {var $foo = bar}
και
να διαδώσετε δεδομένα σε ολόκληρη την αλυσίδα κληρονομικότητας:
Κληρονομικότητα πολλαπλών επιπέδων
Μπορείτε να χρησιμοποιήσετε όσα επίπεδα κληρονομικότητας χρειάζεστε. Ένας συνηθισμένος τρόπος χρήσης της κληρονομικότητας διάταξης είναι η ακόλουθη προσέγγιση τριών επιπέδων:
- Δημιουργήστε ένα πρότυπο
layout.latte
που κρατάει την κύρια εμφάνιση και αίσθηση του ιστότοπού σας. - Δημιουργήστε ένα πρότυπο
layout-SECTIONNAME.latte
για κάθε τμήμα του ιστότοπού σας. Για παράδειγμα,layout-news.latte
,layout-blog.latte
κ.λπ. Όλα αυτά τα πρότυπα επεκτείνουν τοlayout.latte
και περιλαμβάνουν στυλ/σχεδιασμό για κάθε τμήμα. - Δημιουργήστε μεμονωμένα πρότυπα για κάθε τύπο σελίδας, όπως ένα άρθρο ειδήσεων ή μια καταχώρηση σε ιστολόγιο. Αυτά τα πρότυπα επεκτείνουν το κατάλληλο πρότυπο τμήματος.
Κληρονομικότητα δυναμικής διάταξης
Μπορείτε να χρησιμοποιήσετε μια μεταβλητή ή οποιαδήποτε έκφραση PHP ως όνομα του προτύπου γονέα, ώστε η κληρονομικότητα να συμπεριφέρεται δυναμικά:
Μπορείτε επίσης να χρησιμοποιήσετε το API Latte για να επιλέξετε αυτόματα το πρότυπο διάταξης.
Συμβουλές
Ακολουθούν ορισμένες συμβουλές για την εργασία με την κληρονομικότητα διάταξης:
- Εάν χρησιμοποιείτε το
{layout}
σε ένα πρότυπο, πρέπει να είναι η πρώτη ετικέτα προτύπου σε αυτό το πρότυπο. - Η διάταξη μπορεί να αναζητηθεί
αυτόματα (όπως στους παρουσιαστές). Σε αυτή την
περίπτωση, αν το πρότυπο δεν πρέπει να έχει διάταξη, θα το υποδείξει με
την ετικέτα
{layout none}
. - Η ετικέτα
{layout}
έχει ψευδώνυμο{extends}
. - Το όνομα αρχείου του εκτεταμένου προτύπου εξαρτάται από τον φορτωτή προτύπων.
- Μπορείτε να έχετε όσα μπλοκ θέλετε. Θυμηθείτε, τα υποδείγματα-παιδιά δεν χρειάζεται να ορίζουν όλα τα μπλοκ γονέων, οπότε μπορείτε να συμπληρώσετε λογικές προεπιλογές σε πολλά μπλοκ και στη συνέχεια να ορίσετε μόνο αυτά που χρειάζεστε αργότερα.
Μπλοκ {block}
Βλέπε επίσης ανώνυμο {block}
Ένα μπλοκ παρέχει έναν τρόπο να αλλάξετε τον τρόπο απόδοσης ενός συγκεκριμένου τμήματος ενός προτύπου, αλλά δεν παρεμβαίνει με κανέναν τρόπο στη λογική γύρω από αυτό. Ας πάρουμε το παρακάτω παράδειγμα για να δείξουμε πώς λειτουργεί ένα μπλοκ και κυρίως πώς δεν λειτουργεί:
Αν αποδώσετε αυτό το πρότυπο, το αποτέλεσμα θα είναι ακριβώς το ίδιο με ή χωρίς τις ετικέτες μπλοκ. Τα μπλοκ έχουν πρόσβαση σε μεταβλητές από εξωτερικά πεδία εφαρμογής. Είναι απλώς ένας τρόπος για να το κάνετε να μπορεί να παρακαμφθεί από ένα πρότυπο-παιδί:
Τώρα, κατά την απόδοση του παιδικού προτύπου, ο βρόχος θα
χρησιμοποιήσει το μπλοκ που ορίζεται στο παιδικό πρότυπο child.Latte
αντί για αυτό που ορίζεται στο βασικό parent.Latte
; το εκτελούμενο
πρότυπο είναι τότε ισοδύναμο με το ακόλουθο:
Ωστόσο, αν δημιουργήσουμε μια νέα μεταβλητή μέσα σε ένα μπλοκ με όνομα ή αντικαταστήσουμε μια τιμή μιας υπάρχουσας, η αλλαγή θα είναι ορατή μόνο μέσα στο μπλοκ:
Τα περιεχόμενα του μπλοκ μπορούν να τροποποιηθούν από φίλτρα. Το ακόλουθο παράδειγμα αφαιρεί όλη την HTML και την αλλαγή τίτλου:
Η ετικέτα μπορεί επίσης να γραφτεί ως n:attribute:
Τοπικά μπλοκ
Κάθε μπλοκ παρακάμπτει το περιεχόμενο του γονικού μπλοκ με το ίδιο όνομα. Εκτός από τα τοπικά μπλοκ. Είναι κάτι σαν τις ιδιωτικές μεθόδους της κλάσης. Μπορείτε να δημιουργήσετε ένα πρότυπο χωρίς να ανησυχείτε ότι – λόγω σύμπτωσης των ονομάτων των μπλοκ – θα αντικατασταθούν από το δεύτερο πρότυπο.
Εκτύπωση μπλοκ {include}
Βλέπε επίσης {include file}
Για να εκτυπώσετε ένα μπλοκ σε ένα συγκεκριμένο σημείο,
χρησιμοποιήστε την ετικέτα {include blockname}
:
Μπορείτε επίσης να εμφανίσετε μπλοκ από άλλο πρότυπο:
εκτός αν το μπλοκ έχει οριστεί στο ίδιο αρχείο όπου περιλαμβάνεται. Ωστόσο, έχουν πρόσβαση στις παγκόσμιες μεταβλητές.
Μπορείτε να περάσετε μεταβλητές στο μπλοκ με τον ακόλουθο τρόπο:
Μπορείτε να χρησιμοποιήσετε μια μεταβλητή ή οποιαδήποτε έκφραση
στην PHP ως όνομα μπλοκ. Σε αυτή την περίπτωση, προσθέστε τη λέξη-κλειδί
block
πριν από τη μεταβλητή, ώστε να είναι γνωστό κατά τη
μεταγλώττιση ότι πρόκειται για μπλοκ και όχι για insert
template, το όνομα του οποίου θα μπορούσε επίσης να βρίσκεται στη
μεταβλητή:
Το μπλοκ μπορεί επίσης να εκτυπωθεί μέσα στον εαυτό του, κάτι που είναι χρήσιμο, για παράδειγμα, κατά την απόδοση μιας δενδρικής δομής:
Αντί του {include menu, ...}
μπορούμε επίσης να γράψουμε
{include this, ...}
όπου this
σημαίνει τρέχον μπλοκ.
Το εκτυπωμένο περιεχόμενο μπορεί να τροποποιηθεί με φίλτρα. Το ακόλουθο παράδειγμα αφαιρεί όλη την HTML και την αλλαγή του τίτλου:
Γονικό μπλοκ
Εάν πρέπει να εκτυπώσετε το περιεχόμενο του μπλοκ από το γονικό
πρότυπο, η δήλωση {include parent}
θα κάνει το κόλπο. Αυτό είναι χρήσιμο
αν θέλετε να προσθέσετε στα περιεχόμενα ενός γονικού μπλοκ αντί να το
παρακάμψετε πλήρως.
Ορισμοί {define}
Εκτός από τα μπλοκ, υπάρχουν επίσης „ορισμοί“ στο Latte. Είναι συγκρίσιμοι με τις συναρτήσεις στις κανονικές γλώσσες προγραμματισμού. Είναι χρήσιμοι για την επαναχρησιμοποίηση τμημάτων προτύπων για να μην επαναλαμβάνεστε.
Η Latte προσπαθεί να κρατήσει τα πράγματα απλά, οπότε βασικά οι ορισμοί είναι το ίδιο με τα μπλοκ, και ό,τι λέγεται για τα μπλοκ ισχύει και για τους ορισμούς. Διαφέρουν από τα μπλοκ σε αυτό:
- περικλείονται σε ετικέτες
{define}
- αποδίδονται μόνο όταν εισάγονται μέσω
{include}
- μπορείτε να ορίσετε παραμέτρους για αυτά όπως οι συναρτήσεις στην PHP
Φανταστείτε ότι έχετε ένα βοηθητικό πρότυπο με μια συλλογή ορισμών για το πώς να σχεδιάζετε φόρμες HTML.
Τα επιχειρήματα ενός ορισμού είναι πάντοτε προαιρετικά με
προεπιλεγμένη τιμή null
, εκτός εάν έχει καθοριστεί προεπιλεγμένη
τιμή (εδώ 'text'
είναι η προεπιλεγμένη τιμή για το $type
). Οι
τύποι παραμέτρων μπορούν επίσης να δηλωθούν:
{define input, string $name, ...}
.
Το πρότυπο με τους ορισμούς φορτώνεται χρησιμοποιώντας {import}
. Οι ίδιοι οι ορισμοί απεικονίζονται με
τον ίδιο τρόπο όπως και τα μπλοκ:
Οι ορισμοί δεν έχουν πρόσβαση στις μεταβλητές του ενεργού πλαισίου, αλλά έχουν πρόσβαση σε παγκόσμιες μεταβλητές.
Δυναμικά ονόματα μπλοκ
Η Latte επιτρέπει μεγάλη ευελιξία στον ορισμό των μπλοκ, επειδή το όνομα
του μπλοκ μπορεί να είναι οποιαδήποτε έκφραση της PHP. Αυτό το
παράδειγμα ορίζει τρία μπλοκ με τα ονόματα hi-Peter
, hi-John
και
hi-Mary
:
Για παράδειγμα, μπορούμε να επαναπροσδιορίσουμε μόνο ένα μπλοκ σε ένα πρότυπο παιδί:
Έτσι, η έξοδος θα μοιάζει με αυτό:
Έλεγχος ύπαρξης μπλοκ {ifset}
Βλέπε επίσης {ifset $var}
Χρησιμοποιήστε τη δοκιμή {ifset blockname}
για να ελέγξετε αν ένα
μπλοκ (ή περισσότερα μπλοκ) υπάρχει στο τρέχον πλαίσιο:
Μπορείτε να χρησιμοποιήσετε μια μεταβλητή ή οποιαδήποτε έκφραση
στην PHP ως όνομα μπλοκ. Σε αυτή την περίπτωση, προσθέστε τη λέξη-κλειδί
block
πριν από τη μεταβλητή για να καταστήσετε σαφές ότι δεν είναι
η μεταβλητή που ελέγχεται:
Η ύπαρξη μπλοκ επιστρέφεται επίσης από τη συνάρτηση hasBlock()
:
Συμβουλές
Ακολουθούν μερικές συμβουλές για την εργασία με μπλοκ:
- Το τελευταίο μπλοκ ανώτατου επιπέδου δεν χρειάζεται να έχει ετικέτα κλεισίματος (το μπλοκ τελειώνει με το τέλος του εγγράφου). Αυτό απλοποιεί τη συγγραφή των προτύπων-παιδιών, τα οποία ένα πρωτογενές μπλοκ.
- Για μεγαλύτερη αναγνωσιμότητα, μπορείτε προαιρετικά να δώσετε ένα
όνομα στην ετικέτα
{/block}
, για παράδειγμα{/block footer}
. Ωστόσο, το όνομα πρέπει να ταιριάζει με το όνομα του μπλοκ. Σε μεγαλύτερα πρότυπα, αυτή η τεχνική σας βοηθά να βλέπετε ποιες ετικέτες μπλοκ κλείνουν. - Δεν μπορείτε να ορίσετε απευθείας πολλαπλές ετικέτες μπλοκ με το ίδιο όνομα στο ίδιο πρότυπο. Αυτό όμως μπορεί να επιτευχθεί με τη χρήση δυναμικών ονομάτων μπλοκ.
- Μπορείτε να χρησιμοποιήσετε n:attributes για να
ορίσετε μπλοκ όπως
<h1 n:block=title>Welcome to my awesome homepage</h1>
- Τα μπλοκ μπορούν επίσης να χρησιμοποιηθούν χωρίς ονόματα μόνο για
την εφαρμογή των φίλτρων στην
έξοδο:
{block|strip} hello {/block}
Οριζόντια επαναχρησιμοποίηση {import}
Η οριζόντια επαναχρησιμοποίηση είναι ο τρίτος μηχανισμός
επαναχρησιμοποίησης και κληρονομικότητας στο Latte. Επιτρέπει τη
φόρτωση μπλοκ από άλλα πρότυπα. Είναι παρόμοιο με τη δημιουργία ενός
αρχείου με βοηθητικές συναρτήσεις στην PHP και στη συνέχεια τη φόρτωσή
του χρησιμοποιώντας το require
.
Ενώ η κληρονομικότητα διάταξης προτύπου είναι ένα από τα πιο ισχυρά χαρακτηριστικά του Latte, περιορίζεται στην απλή κληρονομικότητα – ένα πρότυπο μπορεί να επεκτείνει μόνο ένα άλλο πρότυπο. Η οριζόντια επαναχρησιμοποίηση είναι ένας τρόπος για την επίτευξη πολλαπλής κληρονομικότητας.
Ας έχουμε ένα σύνολο από ορισμούς μπλοκ:
Χρησιμοποιώντας την εντολή {import}
, εισάγετε όλα τα μπλοκ και
τους ορισμούς που ορίζονται στο blocks.latte
σε ένα
άλλο πρότυπο:
(π.χ. χρησιμοποιήστε την εντολή {import}
στο layout.latte
), τα
μπλοκ θα είναι διαθέσιμα και σε όλα τα θυγατρικά πρότυπα, πράγμα πολύ
βολικό.
Το πρότυπο που πρόκειται να εισαχθεί (π.χ. blocks.latte
) δεν πρέπει να
επεκτείνει άλλο πρότυπο, δηλαδή να
χρησιμοποιήσετε το {layout}
. Ωστόσο, μπορεί να εισάγει άλλα
πρότυπα.
Η ετικέτα {import}
πρέπει να είναι η πρώτη ετικέτα προτύπου μετά
το {layout}
. Το όνομα του προτύπου μπορεί να είναι οποιαδήποτε
έκφραση PHP:
Μπορείτε να χρησιμοποιήσετε όσες δηλώσεις {import}
θέλετε σε
οποιοδήποτε συγκεκριμένο πρότυπο. Αν δύο εισαγόμενα πρότυπα ορίζουν
το ίδιο μπλοκ, το πρώτο κερδίζει. Ωστόσο, η υψηλότερη προτεραιότητα
δίνεται στο κύριο πρότυπο, το οποίο μπορεί να αντικαταστήσει
οποιοδήποτε εισαγόμενο μπλοκ.
Το περιεχόμενο των μπλοκ που έχουν αντικατασταθεί μπορεί να διατηρηθεί με την εισαγωγή του μπλοκ με τον ίδιο τρόπο όπως ένα γονικό μπλοκ:
Σε αυτό το παράδειγμα, το {include parent}
θα καλέσει σωστά το μπλοκ
sidebar
από το πρότυπο blocks.latte
.
Κληρονομικότητα μονάδων {embed}
Η κληρονομικότητα μονάδας μεταφέρει την ιδέα της κληρονομικότητας διάταξης στο επίπεδο των τμημάτων περιεχομένου. Ενώ η κληρονομικότητα διάταξης λειτουργεί με „σκελετούς εγγράφων“, οι οποίοι ζωντανεύουν από πρότυπα-παιδιά, η κληρονομικότητα μονάδων σας επιτρέπει να δημιουργείτε σκελετούς για μικρότερες μονάδες περιεχομένου και να τους επαναχρησιμοποιείτε οπουδήποτε θέλετε.
Στην κληρονομικότητα μονάδων η ετικέτα {embed}
είναι το κλειδί.
Συνδυάζει τη συμπεριφορά των {include}
και {layout}
. Σας
επιτρέπει να συμπεριλάβετε τα περιεχόμενα ενός άλλου προτύπου ή μπλοκ
και να περάσετε προαιρετικά μεταβλητές, όπως ακριβώς κάνει το
{include}
. Σας επιτρέπει επίσης να παρακάμψετε οποιοδήποτε μπλοκ
που ορίζεται μέσα στο συμπεριλαμβανόμενο πρότυπο, όπως κάνει το
{layout}
.
Για παράδειγμα, θα χρησιμοποιήσουμε το πτυσσόμενο στοιχείο
ακορντεόν. Ας ρίξουμε μια ματιά στον σκελετό του στοιχείου στο πρότυπο
collapsible.latte
:
Οι ετικέτες {block}
ορίζουν δύο μπλοκ που μπορούν να συμπληρώσουν
τα πρότυπα-παιδιά. Ναι, όπως και στην περίπτωση του προτύπου γονέα στο
πρότυπο κληρονομικότητας διάταξης. Βλέπετε επίσης τη μεταβλητή
$modifierClass
.
Ας χρησιμοποιήσουμε το στοιχείο μας στο πρότυπο. Σε αυτό το σημείο
έρχεται το {embed}
. Είναι ένα εξαιρετικά ισχυρό κομμάτι του κιτ που
μας επιτρέπει να κάνουμε όλα τα πράγματα: να συμπεριλάβουμε τα
περιεχόμενα του προτύπου του στοιχείου, να προσθέσουμε μεταβλητές σε
αυτό και να προσθέσουμε μπλοκ με προσαρμοσμένη HTML σε αυτό:
Η έξοδος μπορεί να μοιάζει κάπως έτσι:
Τα μπλοκ μέσα σε ετικέτες ενσωμάτωσης σχηματίζουν ένα ξεχωριστό
επίπεδο, ανεξάρτητο από άλλα μπλοκ. Επομένως, μπορούν να έχουν το ίδιο
όνομα με το μπλοκ που βρίσκεται έξω από την ενσωμάτωση και δεν
επηρεάζονται με κανέναν τρόπο. Χρησιμοποιώντας την ετικέτα include μέσα στις ετικέτες {embed}
μπορείτε να
εισάγετε μπλοκ που δημιουργήθηκαν εδώ, μπλοκ από το ενσωματωμένο
πρότυπο (τα οποία δεν είναι τοπικά), καθώς και
μπλοκ από το κύριο πρότυπο τα οποία είναι τοπικά. Μπορείτε επίσης
να εισάγετε μπλοκ από άλλα αρχεία:
Τα ενσωματωμένα πρότυπα δεν έχουν πρόσβαση στις μεταβλητές του ενεργού πλαισίου, αλλά έχουν πρόσβαση στις παγκόσμιες μεταβλητές.
Με το {embed}
μπορείτε να εισάγετε όχι μόνο πρότυπα αλλά και άλλα
μπλοκ, οπότε το προηγούμενο παράδειγμα θα μπορούσε να γραφτεί
ως εξής:
Αν περάσουμε μια έκφραση στο {embed}
και δεν είναι σαφές αν
πρόκειται για μπλοκ ή για όνομα αρχείου, προσθέστε τη λέξη-κλειδί
block
ή file
:
Περιπτώσεις χρήσης
Υπάρχουν διάφοροι τύποι κληρονομικότητας και επαναχρησιμοποίησης κώδικα στο Latte. Ας συνοψίσουμε τις κύριες έννοιες για περισσότερη σαφήνεια:
{include template}
Περίπτωση χρήσης: Χρήση των header.latte
& footer.latte
μέσα
στο layout.latte
.
header.latte
footer.latte
layout.latte
{layout}
Περίπτωση χρήσης: Επέκταση του layout.latte
μέσα στο
homepage.latte
& about.latte
.
layout.latte
homepage.latte
about.latte
{import}
Περίπτωση χρήσης: sidebar.latte
σε single.product.latte
&
single.service.latte
.
sidebar.latte
single.product.latte
single.service.latte
{define}
Περίπτωση χρήσης: Μια συνάρτηση που παίρνει κάποιες μεταβλητές και εξάγει κάποια σήμανση.
form.latte
profile.service.latte
{embed}
Περίπτωση χρήσης: Ενσωμάτωση του pagination.latte
στο
product.table.latte
& service.table.latte
.
pagination.latte
product.table.latte
service.table.latte