Πρακτικές Ανάπτυξης
Εγκατάσταση
Ο καλύτερος τρόπος για να εγκαταστήσετε το Latte είναι χρησιμοποιώντας το Composer:
composer require latte/latte
Υποστηριζόμενες εκδόσεις PHP (ισχύει για τις τελευταίες εκδόσεις patch του Latte):
έκδοση | συμβατό με PHP |
---|---|
Latte 3.0 | PHP 8.0 – 8.2 |
Πώς να Αποδώσετε ένα Template
Πώς να αποδώσετε ένα template; Αυτός ο απλός κώδικας είναι αρκετός:
$latte = new Latte\Engine;
// cache directory
$latte->setTempDirectory('/path/to/tempdir');
$params = [ /* template variables */ ];
// or $params = new TemplateParameters(/* ... */);
// render to output
$latte->render('template.latte', $params);
// render to variable
$output = $latte->renderToString('template.latte', $params);
Οι παράμετροι μπορεί να είναι ένας πίνακας ή, ακόμα καλύτερα, ένα object, το οποίο εξασφαλίζει έλεγχο τύπου και υποδείξεις σε επεξεργαστές.
Παραδείγματα χρήσης μπορείτε επίσης να βρείτε στο αποθετήριο Latte examples.
Απόδοση και Cache
Τα templates στο Latte είναι εξαιρετικά γρήγορα, καθώς το Latte τα μεταγλωττίζει απευθείας σε κώδικα PHP και τα αποθηκεύει στην προσωρινή μνήμη στον δίσκο. Επομένως, δεν έχουν επιπλέον επιβάρυνση σε σύγκριση με τα templates που γράφονται σε καθαρή PHP.
Η προσωρινή μνήμη αναδημιουργείται αυτόματα κάθε φορά που αλλάζετε το πηγαίο αρχείο. Έτσι, κατά τη διάρκεια της ανάπτυξης, μπορείτε εύκολα να επεξεργαστείτε τα templates του Latte και να δείτε αμέσως τις αλλαγές στον περιηγητή. Μπορείτε να απενεργοποιήσετε αυτή τη λειτουργία σε περιβάλλον παραγωγής για να εξοικονομήσετε λίγη απόδοση:
$latte->setAutoRefresh(false);
Κατά την ανάπτυξη σε έναν διακομιστή παραγωγής, η αρχική δημιουργία της προσωρινής μνήμης, ειδικά για μεγαλύτερες εφαρμογές, μπορεί φυσικά να διαρκέσει λίγο. Το Latte διαθέτει ενσωματωμένη πρόληψη έναντι του cache stampede. Αυτή είναι μια κατάσταση όπου ένας μεγάλος αριθμός ταυτόχρονων αιτημάτων φτάνει, τα οποία ξεκινούν το Latte, και επειδή η προσωρινή μνήμη δεν υπάρχει ακόμα, όλα θα άρχιζαν να τη δημιουργούν ταυτόχρονα. Αυτό θα επιβάρυνε υπερβολικά τον διακομιστή. Το Latte είναι έξυπνο και σε περίπτωση πολλαπλών ταυτόχρονων αιτημάτων, μόνο το πρώτο νήμα δημιουργεί την προσωρινή μνήμη, τα άλλα περιμένουν και στη συνέχεια τη χρησιμοποιούν.
Παράμετροι ως Κλάση
Καλύτερα από το να περνάτε μεταβλητές στο template ως πίνακας είναι να δημιουργήσετε μια κλάση. Θα αποκτήσετε έτσι type-safe notation, pleasant hinting in IDEs και έναν τρόπο για registering filters και functions.
class MailTemplateParameters
{
public function __construct(
public string $lang,
public Address $address,
public string $subject,
public array $items,
public ?float $price = null,
) {}
}
$latte->render('mail.latte', new MailTemplateParameters(
lang: $this->lang,
subject: $title,
price: $this->getPrice(),
items: [],
address: $userAddress,
));
Απενεργοποίηση Αυτόματης Διαφυγής Μεταβλητής
Εάν μια μεταβλητή περιέχει μια συμβολοσειρά HTML, μπορείτε να την
επισημάνετε έτσι ώστε το Latte να μην τη διαφεύγει αυτόματα (και επομένως
διπλά). Αυτό αποφεύγει την ανάγκη χρήσης του |noescape
στο template.
Ο ευκολότερος τρόπος είναι να τυλίξετε τη συμβολοσειρά σε ένα
αντικείμενο Latte\Runtime\Html
:
$params = [
'articleBody' => new Latte\Runtime\Html($article->htmlBody),
];
Το Latte επίσης δεν διαφεύγει όλα τα αντικείμενα που υλοποιούν τη
διεπαφή Latte\HtmlStringable
. Μπορείτε να δημιουργήσετε τη δική σας κλάση
της οποίας η μέθοδος __toString()
θα επιστρέφει κώδικα HTML που δεν θα
διαφεύγεται αυτόματα:
class Emphasis extends Latte\HtmlStringable
{
public function __construct(
private string $str,
) {
}
public function __toString(): string
{
return '<em>' . htmlspecialchars($this->str) . '</em>';
}
}
$params = [
'foo' => new Emphasis('hello'),
];
Η μέθοδος __toString
πρέπει να επιστρέφει έγκυρο HTML και να
διασφαλίζει τη διαφυγή των παραμέτρων, διαφορετικά μπορεί να προκύψει
ευπάθεια XSS!
Πώς να Επεκτείνετε το Latte με Φίλτρα, Tags, κ.λπ.
Πώς να προσθέσετε το δικό σας φίλτρο, συνάρτηση, tag, κ.λπ. στο Latte; Αυτό καλύπτεται στο κεφάλαιο extending Latte. Εάν θέλετε να επαναχρησιμοποιήσετε τις τροποποιήσεις σας σε διαφορετικά έργα ή να τις μοιραστείτε με άλλους, θα πρέπει να create an extension.
Οποιοσδήποτε Κώδικας στο Template {php ...}
Μέσα στο tag {do}
, μπορείτε να
γράψετε μόνο εκφράσεις PHP, οπότε δεν μπορείτε, για παράδειγμα, να
εισαγάγετε κατασκευές όπως if ... else
ή εντολές που τελειώνουν με
ερωτηματικό.
Ωστόσο, μπορείτε να καταχωρήσετε την επέκταση RawPhpExtension
, η
οποία προσθέτει το tag {php ...}
. Χρησιμοποιώντας το, μπορείτε να
εισαγάγετε οποιονδήποτε κώδικα PHP. Δεν ισχύουν κανόνες λειτουργίας
sandbox, οπότε η χρήση είναι ευθύνη του συγγραφέα του template.
$latte->addExtension(new Latte\Essential\RawPhpExtension);
Έλεγχος Δημιουργημένου Κώδικα
Το Latte μεταγλωττίζει τα templates σε κώδικα PHP. Φυσικά, διασφαλίζει ότι ο
δημιουργημένος κώδικας είναι συντακτικά έγκυρος. Ωστόσο, όταν
χρησιμοποιείτε επεκτάσεις τρίτων ή το RawPhpExtension
, το Latte δεν
μπορεί να εγγυηθεί την ορθότητα του δημιουργημένου αρχείου. Είναι
επίσης δυνατό να γράψετε κώδικα στην PHP που είναι συντακτικά σωστός,
αλλά απαγορευμένος (για παράδειγμα, ανάθεση τιμής στη μεταβλητή
$this
) και προκαλεί PHP Compile Error. Εάν γράψετε μια τέτοια λειτουργία σε
ένα template, θα συμπεριληφθεί και στον δημιουργημένο κώδικα PHP. Δεδομένου
ότι υπάρχουν περίπου διακόσιες διαφορετικές απαγορευμένες
λειτουργίες στην PHP, το Latte δεν φιλοδοξεί να τις ανιχνεύσει. Η ίδια η PHP
θα τις επισημάνει κατά την απόδοση, κάτι που συνήθως δεν αποτελεί
πρόβλημα.
Ωστόσο, υπάρχουν καταστάσεις όπου θέλετε να γνωρίζετε ήδη κατά τη
μεταγλώττιση του template ότι δεν περιέχει PHP Compile Errors. Ειδικά εάν τα templates
μπορούν να επεξεργαστούν από χρήστες, ή εάν χρησιμοποιείτε το Sandbox. Σε αυτή την περίπτωση, ελέγξτε τα templates
ήδη κατά τη μεταγλώττιση. Αυτή η λειτουργικότητα ενεργοποιείται με τη
μέθοδο Engine::enablePhpLint()
. Δεδομένου ότι χρειάζεται να καλέσει το
εκτελέσιμο PHP για τον έλεγχο, περάστε τη διαδρομή προς αυτό ως
παράμετρο:
$latte = new Latte\Engine;
$latte->enablePhpLinter('/path/to/php');
try {
$latte->compile('home.latte');
} catch (Latte\CompileException $e) {
// catches errors in Latte and also Compile Errors in PHP
echo 'Error: ' . $e->getMessage();
}
Τοπικές Ρυθμίσεις
Το Latte σας επιτρέπει να ορίσετε τις τοπικές ρυθμίσεις, οι οποίες
επηρεάζουν τη μορφοποίηση αριθμών, ημερομηνιών και τη ταξινόμηση.
Ορίζεται χρησιμοποιώντας τη μέθοδο setLocale()
. Το αναγνωριστικό
τοπικών ρυθμίσεων ακολουθεί το πρότυπο IETF language tag, το οποίο
χρησιμοποιείται από την επέκταση PHP intl
. Αποτελείται από τον
κωδικό γλώσσας και προαιρετικά τον κωδικό χώρας, π.χ. en_US
για
Αγγλικά στις Ηνωμένες Πολιτείες, de_DE
για Γερμανικά στη
Γερμανία, κ.λπ.
$latte = new Latte\Engine;
$latte->setLocale('el');
Η ρύθμιση των τοπικών ρυθμίσεων επηρεάζει τα φίλτρα localDate, sort, number και bytes.
Απαιτεί την επέκταση PHP intl
. Η ρύθμιση στο Latte δεν
επηρεάζει τις καθολικές ρυθμίσεις τοπικών ρυθμίσεων στην PHP.
Αυστηρή Λειτουργία
Στην αυστηρή λειτουργία ανάλυσης, το Latte ελέγχει εάν λείπουν τα
κλεισίματα των tags HTML και επίσης απαγορεύει τη χρήση της μεταβλητής
$this
. Την ενεργοποιείτε ως εξής:
$latte = new Latte\Engine;
$latte->setStrictParsing();
Για να ενεργοποιήσετε τη δημιουργία templates με την κεφαλίδα
declare(strict_types=1)
, κάντε το ως εξής:
$latte = new Latte\Engine;
$latte->setStrictTypes();
Μετάφραση σε Templates
Χρησιμοποιώντας την επέκταση TranslatorExtension
, προσθέτετε τα tags {_...}
, {translate}
και το φίλτρο translate
στο template.
Χρησιμοποιούνται για τη μετάφραση τιμών ή τμημάτων του template σε άλλες
γλώσσες. Ως παράμετρο, καθορίζουμε τη μέθοδο (PHP callable) που εκτελεί τη
μετάφραση:
class MyTranslator
{
public function __construct(private string $lang)
{}
public function translate(string $original): string
{
// create $translated from $original according to $this->lang
return $translated;
}
}
$translator = new MyTranslator($lang);
$extension = new Latte\Essential\TranslatorExtension(
$translator->translate(...), // [$translator, 'translate'] in PHP 8.0
);
$latte->addExtension($extension);
Ο Translator καλείται κατά το χρόνο εκτέλεσης κατά την απόδοση του template. Ωστόσο, το Latte μπορεί να μεταφράσει όλα τα στατικά κείμενα ήδη κατά τη μεταγλώττιση του template. Αυτό εξοικονομεί απόδοση, καθώς κάθε συμβολοσειρά μεταφράζεται μόνο μία φορά και η προκύπτουσα μετάφραση γράφεται στη μεταγλωττισμένη μορφή. Έτσι, δημιουργούνται πολλαπλές μεταγλωττισμένες εκδόσεις του template στον κατάλογο cache, μία για κάθε γλώσσα. Για να το κάνετε αυτό, απλά καθορίστε τη γλώσσα ως δεύτερη παράμετρο:
$extension = new Latte\Essential\TranslatorExtension(
$translator->translate(...),
$lang,
);
Στατικό κείμενο σημαίνει κάτι σαν {_'hello'}
ή
{translate}hello{/translate}
. Μη στατικά κείμενα, όπως {_$foo}
, θα
συνεχίσουν να μεταφράζονται κατά το χρόνο εκτέλεσης.
Μπορείτε επίσης να περάσετε πρόσθετες παραμέτρους στον μεταφραστή
από το template χρησιμοποιώντας {_$original, foo: bar}
ή {translate foo: bar}
,
τις οποίες λαμβάνει ως πίνακα $params
:
public function translate(string $original, ...$params): string
{
// $params['foo'] === 'bar'
}
Debugging και Tracy
Το Latte προσπαθεί να κάνει την ανάπτυξη όσο το δυνατόν πιο ευχάριστη
για εσάς. Υπάρχουν τρία tags ειδικά για σκοπούς debugging: {dump}
, {debugbreak}
και {trace}
.
Θα έχετε τη μεγαλύτερη άνεση εάν εγκαταστήσετε επίσης το εξαιρετικό debugging tool Tracy και ενεργοποιήσετε το πρόσθετο για το Latte:
// enable Tracy
Tracy\Debugger::enable();
$latte = new Latte\Engine;
// activate the extension for Tracy
$latte->addExtension(new Latte\Bridges\Tracy\TracyExtension);
Τώρα, όλα τα σφάλματα θα εμφανίζονται σε μια καθαρή κόκκινη οθόνη, συμπεριλαμβανομένων των σφαλμάτων στα templates με επισήμανση γραμμής και στήλης (video). Ταυτόχρονα, στην κάτω δεξιά γωνία στο λεγόμενο Tracy Bar, θα εμφανιστεί μια καρτέλα για το Latte, όπου όλα τα αποδιδόμενα templates και οι αμοιβαίες σχέσεις τους είναι ορατά με σαφήνεια (συμπεριλαμβανομένης της δυνατότητας κλικ στο template ή στον μεταγλωττισμένο κώδικα) καθώς και οι μεταβλητές:

Δεδομένου ότι το Latte μεταγλωττίζει τα templates σε σαφή κώδικα PHP, μπορείτε εύκολα να τα βηματοποιήσετε στο IDE σας.
Linter: Επικύρωση Σύνταξης Template
Το εργαλείο Linter σας βοηθά να ελέγξετε όλα τα templates και να επαληθεύσετε ότι δεν περιέχουν συντακτικά σφάλματα. Εκτελείται από την κονσόλα:
vendor/bin/latte-lint <path>
Η παράμετρος --strict
ενεργοποιεί την strict mode.
Εάν χρησιμοποιείτε τα δικά σας tags, δημιουργήστε επίσης τη δική σας
έκδοση του Linter, π.χ. custom-latte-lint
:
#!/usr/bin/env php
<?php
// enter the actual path to the autoload.php file
require __DIR__ . '/vendor/autoload.php';
$path = $argv[1] ?? '.';
$linter = new Latte\Tools\Linter;
$latte = $linter->getEngine();
// add your individual extensions here
$latte->addExtension(/* ... */);
$ok = $linter->scanDirectory($path);
exit($ok ? 0 : 1);
Εναλλακτικά, μπορείτε να περάσετε το δικό σας αντικείμενο
Latte\Engine
στο Linter:
$latte = new Latte\Engine;
// configure the $latte object here
$linter = new Latte\Tools\Linter(engine: $latte);
Φόρτωση Templates από Συμβολοσειρά
Χρειάζεται να φορτώσετε templates από συμβολοσειρές αντί για αρχεία, ίσως για σκοπούς δοκιμών; Το StringLoader μπορεί να βοηθήσει:
$latte->setLoader(new Latte\Loaders\StringLoader([
'main.file' => '{include other.file}',
'other.file' => '{if true} {$var} {/if}',
]));
$latte->render('main.file', $params);
Χειριστής Εξαιρέσεων
Μπορείτε να ορίσετε τον δικό σας χειριστή για αναμενόμενες
εξαιρέσεις. Οι εξαιρέσεις που προκύπτουν μέσα στο {try}
και στο sandbox θα του περάσουν.
$loggingHandler = function (Throwable $e, Latte\Runtime\Template $template) use ($logger) {
$logger->log($e);
};
$latte = new Latte\Engine;
$latte->setExceptionHandler($loggingHandler);
Αυτόματη Αναζήτηση Layout
Χρησιμοποιώντας το tag {layout}
, ένα template
καθορίζει το γονικό του template. Είναι επίσης δυνατό να γίνει αυτόματη
αναζήτηση του layout, γεγονός που απλοποιεί τη γραφή των templates, καθώς δεν
θα είναι απαραίτητο να συμπεριληφθεί το tag {layout}
σε αυτά.
Αυτό επιτυγχάνεται ως εξής:
$finder = function (Latte\Runtime\Template $template) {
if (!$template->getReferenceType()) {
// returns the path to the layout file
return 'automatic.layout.latte';
}
};
$latte = new Latte\Engine;
$latte->addProvider('coreParentFinder', $finder);
Εάν ένα template δεν πρέπει να έχει layout, το δηλώνει με το tag
{layout none}
.