Зареждане на шаблони
Зареждащите устройства са механизмът, който Latte използва за извличане на изходния код на вашите шаблони. Най-често шаблоните са файлове, съхранявани на диска, но гъвкавата система за зареждане на Latte ви позволява да ги зареждате практически отвсякъде или дори да ги генерирате динамично.
Какво представлява зареждащото устройство?
Обикновено, когато работите с шаблони, си мислите за .latte
файлове, които се намират в структурата на директорията на проекта ви.
С това се занимава файловият зареждач по подразбиране
на Latte. Връзката между името на шаблона (като 'main.latte'
или
'components/card.latte'
) и действителното съдържание на изходния му код
обаче не е задължително да бъде директно съпоставяне на пътя
до файла.
Именно тук се появяват зареждащите устройства. Зареждащото
устройство е обект, отговорен за приемането на име на шаблон
(идентификационен низ) и предоставянето на Latte на неговия изходен код.
Latte разчита изцяло на конфигурирания loader за тази задача. Това се отнася
не само за първоначалния шаблон, поискан чрез $latte->render('main.latte')
,
но също и за всеки шаблон, към който има препратка в рамките на, като
се използват тагове като {include ...}
, {layout ...}
, {embed ...}
или {import ...}
.
Защо да използвате персонализиран зареждащ модул?
- Зареждане от алтернативни източници: Извличане на шаблони, съхранявани в база данни, кеш (като Redis или Memcached), система за контрол на версиите (като Git, въз основа на конкретен commit) или генерирани динамично.
- Въвеждане на потребителски конвенции за именуване: Може да искате да използвате по-кратки псевдоними за шаблоните или да въведете специфична логика на пътя за търсене (например първо да търсите в директорията на темата, а след това да се върнете към директория по подразбиране).
- Добавяне на сигурност или контрол на достъпа: Потребителският зареждащ модул би могъл да провери потребителските права, преди да зареди определени шаблони.
- Предварителна обработка: Макар че като цяло не се препоръчва( по-добре е дасе използва компилатор), теоретично зареждащият модул може да обработи предварително съдържанието на шаблона, преди да го предаде на Latte.
Конфигурирате товарача за вашата инстанция Latte\Engine
, като
използвате метода setLoader()
:
$latte = new Latte\Engine;
// Използване на FileLoader по подразбиране за файлове в '/path/to/templates'
$loader = new Latte\Loaders\FileLoader('/path/to/templates');
$latte->setLoader($loader);
Зареждащото устройство трябва да реализира интерфейса
Latte\Loader
.
Вградени зареждащи устройства
Latte предоставя няколко стандартни зареждащи устройства:
FileLoader
Това е зареждащият модул по подразбиране, използван от
Latte\Engine
, ако не е посочен друг зареждащ модул. Той зарежда
шаблони директно от файловата система.
По желание можете да зададете главна директория, за да ограничите достъпа до нея:
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');
Той разрешава имената на шаблоните относително към текущия шаблон,
когато се използват тагове като {include}
или {layout}
, освен ако
не е зададен абсолютен път.
StringLoader
Този зареждащ модул извлича съдържанието на шаблона от асоциативен масив, в който ключовете са имена на шаблони (идентификатори), а стойностите – низове на изходния код на шаблона. Той е особено полезен за тестване или за малки приложения, където шаблоните могат да се съхраняват в самия 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:Включено съдържание: 10
Ако ви е необходимо да визуализирате само един шаблон директно от
низ, без да се нуждаете от включвания или наследяване, препращащи към
други шаблони с имена в низ, можете да предадете низа директно на
render()
или renderToString()
, когато използвате StringLoader
без масив:
$loader = new StringLoader;
$latte->setLoader($loader);
$templateString = 'Hello {$name}!';
$output = $latte->renderToString($templateString, ['name' => 'Alice']);
// $output съдържа 'Hello Alice!'
Създаване на потребителско зареждане
За да създадете свой собствен зареждащ модул (например за зареждане на шаблони от база данни, кеш, контрол на версиите или друг източник), трябва да създадете клас, който реализира интерфейса Latte\Loader.
Нека разгледаме какво трябва да прави всеки метод.
getContent (string $name): string
Това е основният метод на модула за зареждане. Неговата отговорност е
да извлече и върне пълното съдържание на изходния код за шаблона,
идентифициран от $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
Този метод се занимава с разрешаването на имена на шаблони,
използвани в тагове като {include}
, {layout}
и т.н. Когато Latte
срещне, например, {include 'partial.latte'}
вътре в main.latte
, той
извиква този метод с $name = 'partial.latte'
и $referringName = 'main.latte'
.
Задачата на метода е да преобразува $name
в каноничен
идентификатор (например абсолютен път, уникален ключ за база данни),
който ще се използва при извикване на други методи на зареждащия модул
въз основа на контекста, предоставен от $referringName
.
public function getReferredName(string $name, string $referringName): string
{
return ...;
}
getUniqueId (string $name): string
Latte използва кеш паметта на компилирания шаблон за по-голяма
производителност. Всеки файл на компилиран шаблон се нуждае от
уникално име, получено от идентификатора на изходния шаблон. Този
метод предоставя низ, който уникално идентифицира шаблона
$name
.
За шаблони, базирани на файлове, може да работи абсолютният път. За шаблони от бази данни често се използва комбинация от префикс и идентификатора на базата данни.
public function getUniqueId(string $name): string
{
return ...;
}
Пример: Обикновено зареждане на база данни
Този пример демонстрира основната структура на програма за
зареждане, извличаща шаблони, съхранявани в таблица на базата данни с
име templates
с колони name
(уникален идентификатор),
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;
}
// Този прост пример предполага имена на шаблони ("начална страница", "статия" и т.н.)
// са уникални идентификатори и шаблоните не се препращат относително един към друг.
public function getReferredName(string $name, string $referringName): string
{
return $name;
}
public function getUniqueId(string $name): string
{
// Използването на префикс и самото име е уникално и достатъчно тук
return 'db_' . $name;
}
}
// Използване:
$pdo = new \PDO(/* connection details */);
$loader = new DatabaseLoader($pdo);
$latte->setLoader($loader);
$latte->render('homepage'); // Зарежда шаблон с име 'homepage' от БД
Персонализираните зареждащи устройства ви дават пълен контрол върху това откъде идват вашите Latte шаблони, което позволява интеграция с различни системи за съхранение и работни процеси.