Nette Documentation Preview

syntax
Loaders
*******
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Loaders

Οι Loaders είναι ο μηχανισμός που χρησιμοποιεί το Latte για να αποκτήσει τον πηγαίο κώδικα των προτύπων σας. Συνηθέστερα, τα πρότυπα αποθηκεύονται ως αρχεία στο δίσκο, αλλά χάρη στο ευέλικτο σύστημα των loaders, μπορείτε να τα φορτώσετε πρακτικά από οπουδήποτε ή ακόμη και να τα δημιουργήσετε δυναμικά.

Τι είναι ένας Loader;

Όταν εργάζεστε με πρότυπα, συνήθως φαντάζεστε αρχεία .latte τοποθετημένα στη δομή καταλόγων του project σας. Αυτό το φροντίζει ο προεπιλεγμένος FileLoader στο Latte. Ωστόσο, η σύνδεση μεταξύ του ονόματος ενός προτύπου (όπως 'main.latte' ή 'components/card.latte') και του πραγματικού πηγαίου κώδικά του δεν χρειάζεται να είναι μια άμεση αντιστοίχιση σε μια διαδρομή αρχείου.

Εδώ ακριβώς μπαίνουν στο παιχνίδι οι loaders. Ένας loader είναι ένα αντικείμενο που έχει ως καθήκον να πάρει το όνομα ενός προτύπου (μια αναγνωριστική συμβολοσειρά) και να παρέχει στο Latte τον πηγαίο κώδικά του. Το Latte βασίζεται εξ ολοκλήρου στον διαμορφωμένο loader για αυτή την εργασία. Αυτό ισχύει όχι μόνο για το αρχικό πρότυπο που ζητήθηκε με το $latte->render('main.latte'), αλλά και για κάθε πρότυπο στο οποίο γίνεται αναφορά εντός του χρησιμοποιώντας tags όπως {include ...}, {layout ...}, {embed ...} ή {import ...}.

Γιατί να χρησιμοποιήσετε έναν προσαρμοσμένο loader;

  • Φόρτωση από εναλλακτικές πηγές: Λήψη προτύπων αποθηκευμένων σε βάση δεδομένων, σε cache (όπως Redis ή Memcached), σε σύστημα διαχείρισης εκδόσεων (όπως Git, βάσει συγκεκριμένου commit) ή δυναμικά δημιουργημένων.
  • Υλοποίηση προσαρμοσμένων συμβάσεων ονοματοδοσίας: Μπορεί να θέλετε να χρησιμοποιείτε συντομότερα ψευδώνυμα για πρότυπα ή να υλοποιήσετε συγκεκριμένη λογική διαδρομών αναζήτησης (π.χ. αναζήτηση πρώτα στον κατάλογο θέματος, μετά επιστροφή στον προεπιλεγμένο κατάλογο).
  • Προσθήκη ασφάλειας ή ελέγχου πρόσβασης: Ένας προσαρμοσμένος loader μπορεί να επαληθεύσει τα δικαιώματα χρήστη πριν φορτώσει ορισμένα πρότυπα.
  • Προεπεξεργασία: Αν και γενικά δεν συνιστάται (compilation passes είναι καλύτερα), ένας loader θα μπορούσε θεωρητικά να προεπεξεργαστεί το περιεχόμενο του προτύπου πριν το παραδώσει στο Latte.

Ορίζετε τον loader για μια παρουσία Latte\Engine χρησιμοποιώντας τη μέθοδο setLoader():

$latte = new Latte\Engine;

// Χρήση του προεπιλεγμένου FileLoader για αρχεία στο '/path/to/templates'
$loader = new Latte\Loaders\FileLoader('/path/to/templates');
$latte->setLoader($loader);

Ο loader πρέπει να υλοποιεί το interface Latte\Loader.

Ενσωματωμένοι Loaders

Το Latte προσφέρει αρκετούς τυπικούς loaders:

FileLoader

Αυτός είναι ο προεπιλεγμένος loader που χρησιμοποιείται από την κλάση Latte\Engine, εάν δεν καθοριστεί άλλος. Φορτώνει πρότυπα απευθείας από το σύστημα αρχείων.

Προαιρετικά, μπορείτε να ορίσετε έναν root directory για να περιορίσετε την πρόσβαση:

use Latte\Loaders\FileLoader;

// Το ακόλουθο θα επιτρέψει τη φόρτωση προτύπων μόνο από τον κατάλογο /var/www/html/templates
$loader = new FileLoader('/var/www/html/templates');
$latte->setLoader($loader);

// $latte->render('../../../etc/passwd'); // Αυτό θα προκαλούσε εξαίρεση

// Απόδοση ενός προτύπου που βρίσκεται στο /var/www/html/templates/pages/contact.latte
$latte->render('pages/contact.latte');

Όταν χρησιμοποιείτε tags όπως {include} ή {layout}, επιλύει τα ονόματα των προτύπων σχετικά με το τρέχον πρότυπο, εκτός εάν παρέχεται μια absolute path.

StringLoader

Αυτός ο loader λαμβάνει το περιεχόμενο του προτύπου από έναν συσχετιστικό πίνακα, όπου τα κλειδιά είναι τα ονόματα των προτύπων (identifiers) και οι τιμές είναι οι συμβολοσειρές του πηγαίου κώδικα του προτύπου. Είναι ιδιαίτερα χρήσιμος για testing ή μικρές εφαρμογές όπου τα πρότυπα μπορεί να αποθηκεύονται απευθείας στον κώδικα PHP.

use Latte\Loaders\StringLoader;

$loader = new StringLoader([
	'main.latte' => 'Hello {$name}, include is below:{include helper.latte}',
	'helper.latte' => '{var $x = 10}Included content: {$x}',
	// Προσθέστε περισσότερα πρότυπα όπως απαιτείται
]);

$latte->setLoader($loader);

$latte->render('main.latte', ['name' => 'World']);
// Έξοδος: Hello World, include is below:Included content: 10

Εάν χρειάζεται να αποδώσετε μόνο ένα πρότυπο απευθείας από μια συμβολοσειρά χωρίς την ανάγκη ενσωμάτωσης ή κληρονομικότητας που αναφέρεται σε άλλα ονομασμένα string πρότυπα, μπορείτε να περάσετε τη συμβολοσειρά απευθείας στη μέθοδο render() ή renderToString() όταν χρησιμοποιείτε StringLoader χωρίς πίνακα:

$loader = new StringLoader;
$latte->setLoader($loader);

$templateString = 'Hello {$name}!';
$output = $latte->renderToString($templateString, ['name' => 'Alice']);
// Το $output περιέχει 'Hello Alice!'

Δημιουργία προσαρμοσμένου Loader

Για να δημιουργήσετε έναν προσαρμοσμένο loader (π.χ. για φόρτωση προτύπων από βάση δεδομένων, cache, σύστημα διαχείρισης εκδόσεων ή άλλη πηγή), πρέπει να δημιουργήσετε μια κλάση που υλοποιεί το interface Latte\Loader.

Ας δούμε τι πρέπει να κάνει κάθε μέθοδος.

getContent(string $name)string

Αυτή είναι η βασική μέθοδος του loader. Ο ρόλος της είναι να λάβει και να επιστρέψει τον πλήρη πηγαίο κώδικα του προτύπου που αναγνωρίζεται από το $name (όπως περνά στη μέθοδο $latte->render() ή επιστρέφεται από τη μέθοδο getReferredName()).

Εάν το πρότυπο δεν μπορεί να βρεθεί ή να προσπελαστεί, αυτή η μέθοδος πρέπει να προκαλέσει μια εξαίρεση Latte\RuntimeException.

public function getContent(string $name): string
{
	// Παράδειγμα: Φόρτωση από υποθετικό εσωτερικό αποθηκευτικό χώρο
	$content = $this->storage->read($name);
	if ($content === null) {
		throw new Latte\RuntimeException("Template '$name' cannot be loaded.");
	}
	return $content;
}

getReferredName(string $name, string $referringName)string

Αυτή η μέθοδος χειρίζεται τη μετάφραση των ονομάτων των προτύπων που χρησιμοποιούνται εντός tags όπως {include}, {layout}, κ.λπ. Όταν το Latte συναντήσει, για παράδειγμα, το {include 'partial.latte'} εντός του main.latte, καλεί αυτή τη μέθοδο με $name = 'partial.latte' και $referringName = 'main.latte'.

Ο ρόλος της μεθόδου είναι να μεταφράσει το $name σε ένα canonical identifier (π.χ. absolute path, μοναδικό κλειδί βάσης δεδομένων) που θα χρησιμοποιηθεί κατά την κλήση άλλων μεθόδων του loader, βάσει του context που παρέχεται στο $referringName.

public function getReferredName(string $name, string $referringName): string
{
	return ...;
}

getUniqueId(string $name)string

Το Latte χρησιμοποιεί μια cache μεταγλωττισμένων προτύπων για τη βελτίωση της απόδοσης. Κάθε αρχείο μεταγλωττισμένου προτύπου χρειάζεται ένα μοναδικό όνομα που προέρχεται από το identifier του πηγαίου προτύπου. Αυτή η μέθοδος παρέχει μια συμβολοσειρά που αναγνωρίζει μοναδικά το πρότυπο $name.

Για πρότυπα που βασίζονται σε αρχεία, η absolute path μπορεί να χρησιμεύσει. Για πρότυπα σε βάση δεδομένων, ένας συνδυασμός προθέματος και ID βάσης δεδομένων είναι συνηθισμένος.

public function getUniqueId(string $name): string
{
	return ...;
}

Παράδειγμα: Απλός Loader Βάσης Δεδομένων

Αυτό το παράδειγμα δείχνει τη βασική δομή ενός loader που φορτώνει πρότυπα αποθηκευμένα σε έναν πίνακα βάσης δεδομένων με όνομα templates με στήλες name (μοναδικό identifier), content και updated_at.

use Latte;

class DatabaseLoader implements Latte\Loader
{
	public function __construct(
		private \PDO $db,
	) {
	}

	public function getContent(string $name): string
	{
		$stmt = $this->db->prepare('SELECT content FROM templates WHERE name = ?');
		$stmt->execute([$name]);
		$content = $stmt->fetchColumn();
		if ($content === false) {
			throw new Latte\RuntimeException("Template '$name' not found in database.");
		}
		return $content;
	}

	// Αυτό το απλό παράδειγμα υποθέτει ότι τα ονόματα των προτύπων ('homepage', 'article', κ.λπ.)
	// είναι μοναδικά ID και τα πρότυπα δεν αναφέρονται το ένα στο άλλο σχετικά.
	public function getReferredName(string $name, string $referringName): string
	{
		return $name;
	}

	public function getUniqueId(string $name): string
	{
		// Η χρήση ενός προθέματος και του ίδιου του ονόματος είναι μοναδική και επαρκής εδώ
		return 'db_' . $name;
	}
}

// Χρήση:
$pdo = new \PDO(/* λεπτομέρειες σύνδεσης */);
$loader = new DatabaseLoader($pdo);
$latte->setLoader($loader);
$latte->render('homepage'); // Φορτώνει το πρότυπο με όνομα 'homepage' από τη ΒΔ

Οι προσαρμοσμένοι loaders σας δίνουν πλήρη έλεγχο από πού προέρχονται τα Latte πρότυπά σας, επιτρέποντας την ενσωμάτωση με διάφορα συστήματα αποθήκευσης και ροές εργασίας.