fenom/docs/ru/ext/extend.md
2014-10-31 00:24:56 +03:00

11 KiB
Raw Blame History

Расширение Fenom

Добавление тегов

В шаблонизаторе принято различать два типа тегов: компиляторы и функции. Compilers invokes during compilation template to PHP source and have to Компиляторы вызываются во время преобразования кода шаблона в PHP код и возвращяю PHP код который будет вставлен вместо тега. А функции вызываются непременно в момент выполнения шаблона и возвращают непосредственно данные которые будут отображены. Среди тегов как и в HTML есть строчные и блоковые теги.

Линейные функции

Примитивное добавление функции можно осуществить следующим образом:

$fenom->addFunction(string $function_name, callable $callback[, callable $parser]);

В данном случае запускается стандартный парсер, который автоматически разберет аргументы тега, которые должны быть в формате HTML аттрибутов и отдаст их в функцию ассоциативным массивом:

$fenom->addFunction("some_function", function (array $params) { /* ... */ });

При необходимости можно переопределить парсер на произвольный:

$fenom->addFunction("some_function", $some_function, function (Fenom\Tokenizer $tokenizer, Fenom\Template $template) { /* parse tag */});

Существует более простой способ добавления произвольной функции:

$fenom->addFunctionSmarty(string $function_name, callable $callback);

В данном случае парсер сканирует список аргументов коллбека и попробует сопоставить с аргументами тега.

// ... class XYCalcs ..
public static function calc($x, $y = 5) { /* ... */}
// ...
$fenom->addFunctionSmart('calc', 'XYCalcs::calc');

then

{calc x=$top y=50} or {calc y=50 x=$top} is XYCalcs::calc($top, 50)
{calc x=$top} or {calc $top} is XYCalcs::calc($top)

Таким образом вы успешно можете добавлять Ваши функции или методы.

Блоковые функции

Добавление блоковой функции аналогичен добавлению строковой за исключением того что есть возможность указать парсер для закрывающего тега.

$fenom->addBlockFunction(string $function_name, callable $callback[, callable $parser_open[, callable $parser_close]]);

Сам коллбек принимает первым аргументом контент между открывающим и закрывающим тегом, а вторым аргументом - ассоциативный массив из аргуметов тега:

$fenom->addBlockFunction('some_block_function', function ($content, array $params) { /* ... */});

Линейный компилятор

Добавление строчного компилятора осуществляеться очень просто:

$fenom->addCompiler(string $compiler, callable $parser);

Парсер должен принимать Fenom\Tokenizer $tokenizer, Fenom\Template $template и возвращать PHP код. Компилятор так же можно импортировать из класса автоматически

$fenom->addCompilerSmart(string $compiler, $storage);

$storage может быть как классом так и объектом. В данном случае шаблонизатор будет искать метод tag{$compiler}, который будет взят в качестве парсера тега.

Блоковый компилятор

Добавление блочного компилятора осуществяется двумя способами. Первый

$fenom->addBlockCompiler(string $compiler, array $parsers, array $tags);

где $parser ассоциативный массив ["open" => parser, "close" => parser], сождержащий парсер на открывающий и на закрывающий тег, а $tags содержит список внутренних тегов в формате ["tag_name"] => parser, которые могут быть использованы только с этим компилятором. Второй способ добавления парсера через импортирование из класса или объекта методов:

$fenom->addBlockCompilerSmart(string $compiler, $storage, array $tags, array $floats);

Добавление модификаторов

$fenom->addModifier(string $modifier, callable $callback);
  • $modifier - название модификатора, которое будет использоваться в шаблоне
  • $callback - коллбек, который будет вызван для изменения данных

For example:

{$variable|my_modifier:$param1:$param2}
$fenom->addModifier('my_modifier', function ($variable, $param1, $param2) {
    // ...
});

Расширение тестовго оператора

$fenom->addTest($name, $code);
?>

Расширение глобальной переменной или функции

Fenom обладает определенным набором глобальных переменных и функций. Однако их может не хватать для удобной работы с шаблонами. В этом случае потребуется добавить, переопределить или удалить существующие глобальные переменные или функции. Метод Fenom::addAccessor($name, $parser) позволяет добавить свой обработчик на не известную глобальную переменную или функцию.

$fenom->addAccessor('project', function (Fenom\Tokenizer $tokens) { /* code */ }); 

Указанный вторым аргументом, парсер будет вызван при встречи компилятором конструкции {$.project}. Парсеры вызываются только на момент сборки шаблона, а не во время его выполенения.

Через метод Fenom::addAccessor($name, $parser) можно переопределить уже любую другую существующую глобальную переменную или функцию. Метод Fenom::removeAccessor($name) позволяет удалить любую определенную глобальную переменную или функцию по ее имени.

Источники шаблонов

Шаблоны можно получать из самых разных источников. Когда вы отображаете или вызываете шаблон, либо когда вы подключаете один шаблон к другому, вы указываете источник, вместе с соответствующим путём и названием шаблона. Если источник явно не задан, то используется источник Fenom\Provider, который считывает шаблоны из указанной директории.

Источник шаблонов должен реализовать интерфейс Fenom\ProviderInterface. Используйте метод $fenom->setProvider(...) что бы добавить источник в шаблонизатор, указав навание источника и, если есть необходимость, задать директорию кеша для шаблонов из этого источника. Рассмотрим на примере, реализуем источик шаблонов из базы данных.

Создадим источник:


class DbProvider implements Fenom\ProviderInterface {
    // ...
}

Добавляем источник, указав удобное имя.


$provider = new DbProvider();
$fenom->setProvider("db", $provider, "/tmp/cached/db");

Теперь источник можно использовать.

$fenom->display("db:index.tpl", $vars);
{include "db:menu.tpl"}

Расширение кеша (эксперементальное)

Изначально Fenom не расчитывался на то что кеш скомпиленых шаблонов может располагаться не на файловой системе. Однако, в теории, есть возможность реализовать свое кеширование для скомпиленых шаблонов без переопределения шаблонизатора. Речь идет о своем протоколе, отличным от file://, который можно определить в PHP.

Ваш протол должени иметь класс реализации протокола как указан в документации Stream Wrapper. Класс протокола может иметь не все указанные в документации методы. Вот список методов, необходимых шаблонизатору:

For include:

Note (On 2014-05-13) Zend OpCacher кроме file:// и phar:// не поддеривает другие протоколы.

Пример работы кеша

$this->setCacheDir("redis://hash/compiled/");
  • $cache = fopen("redis://hash/compiled/XnsbfeDnrd.php", "w");
  • fwrite($cache, "... <template content> ...");
  • fclose($cache);
  • rename("redis://hash/compiled/XnsbfeDnrd.php", "redis://hash/compiled/main.php");