Пишем плагин для Смарти
![]() |
Как мы уже говорили в предыдущей статье про Smarty, в нем имеется возможность написания плагинов. Для тех, кто не знает (хотя уже должны знать по статьям про плагины в WordPress), что такое плагин, немного поясню – это некий программный код, который расширяет функциональность какого-то программного средства без изменения ядра этого средства. |
Другими словами, чтобы расширить функциональность Smarty, нам не нужно лезть в его ядро и что-то там менять. Достаточно создать текстовый файл с нужным кодом и поместить этот файл в нужное место. О том, как правильно написать этот код, как назвать и куда положить получившийся файл с этим кодом я и расскажу в этой статье.
Сейчас мы с ходу попробуем написать плагин, который просто будет выводить «Hello, World!». Допустим, мы хотим, чтобы конструкция {hello_world} в шаблоне выводила знаменитую всем фразу.
Для этого создаем файл с именем function.hello_world.php в папке smarty/myplugins со следующим кодом:
function.hello_world.php
<?php
/**
* Smarty plugin
* @package Smarty
* @subpackage plugins
*/
/**
* Smarty {hello_world} plugin
*
* Type: function
* Name: hello_world
* Purpose: outputs "Hello, world!"
* @author Novice <admin at i-novice dot net>
* @param array
* @param Smarty
* @return string
*/
function smarty_function_hello_world($params, &$smarty) {
return 'Hello, world!';
}
?>
index.php
<?
include 'smarty/Smarty.class.php';
$smarty = new Smarty;
$smarty->compile_dir = 'smarty/templates_c';
$smarty->template_dir = 'templates';
$smarty->plugins_dir[] = 'myplugins';
$smarty->display('index.html');
?>
index1.html
<html>
<head>
<title>Page Title</title>
</head>
<body>
{hello_world}
</body>
</html>
Вот мы и написали свой первый плагин для смарти. Теперь поговорим о правилах именования файлов и функций.
Плагины в смарти делятся на несколько типов:
- function – функции
- modifier – модификаторы (например, {$str|capitalize})
- block – блоки (блоковые функции, например {foreach}…{/foreach})
- compiler – функции, запускаемые во время компиляции
- prefilter – фильтр шаблона, запускаемый перед компиляцией (работает с исходником шаблона)
- postfilter – фильтр шаблона, запускаемый после компиляции (работает с результатом компиляции шаблона – php-кодом, который сохраняется на диск в папку templates_c)
- outputfilter – фильтр шаблона, запускаемый после компиляции шаблона, но до вывода результатов этой компиляции
- resource – ресурсы (для взаимодействия с базой данных, сокетами и т.д.)
- insert – для тега {insert}
Мы сейчас писали плагин первой категории, т.е. function, поэтому имя файла начинается с этого слова. А вообще, файл должен называться по таким правилам:
тип_плагина.имя_функции.php
А функция в самом файле плагина должна именоваться по таким правилам:
smarty_[тип_плагина]_[имя_функции]
Иначе смарти не сможет загрузить Ваш плагин. По поводу типов: в этой статье мы говорим только о типах function, modifier и block. Об остальных можно узнать в официальной документации по смарти на сайте . В будущем, в следующих статьях, я может быть затрону и другие типы.
Функции
Заметим, что в объявлении функции smarty_function_hello_world есть два параметра:
- $params – массив с параметрами, переданными этой функции
- $smarty – объект класса Smarty
Переименуем функцию нашего плагина в hello (не забудьте переименовать файл плагина) и сделаем так, чтобы она могла принимать параметры:
function.hello.php
<?
function smarty_function_hello($params, &$smarty) {
if (empty($params['who'])) {
$smarty->trigger_error("hello: missing 'who' parameter");
return;
}
return 'Hello, '.$params['who'].'!';
}
?>
index2.html
<html>
<head>
<title>Page Title</title>
</head>
<body>
{hello who='Novice'}
</body>
</html>
Пример выведет: Hello, Novice!
Модификаторы
Теперь попробуем написать какой-нибудь модификатор переменной шаблона. Назовем его trim и пусть он будет обрезать все пробелы перед и/или после текста переменной (в зависимости от переданного параметра).
modifier.trim.php
<?
function smarty_modifier_trim($string, $type = 'all') {
switch ($type) {
case 'all':
$func = 'trim';
break;
case 'left':
$func = 'ltrim';
break;
case 'right':
$func = 'rtrim';
break;
}
if (empty($func)) {
return $string;
}
return $func($string);
}
?>
index3.html
<html>
<head>
<title>Page Title</title>
</head>
<body>
{' 123 '|trim}456<br />
{' 123 '|trim:right}456<br />
{' 123 '|trim:left}456
</body>
</html>
Выведет:
123456
123456
123 456
Блоки
Теперь поставим себе такую задачу: мы хотим, чтобы каждая первая буква любого слова в тексте шаблона между тегами {ucwords} и {/ucwords} была преобразована в верхний регистр.
Для этого напишем очень простую функцию:
block.ucwords.php
<?
function smarty_block_ucwords($params, $content, &$smarty, &$repeat) {
if (!$repeat) {
return ucwords($content);
}
}
?>
index4.html
<html>
<head>
<title>Page Title</title>
</head>
<body>
Body begin<br />
<br />
{assign var=hello_world value='hello world'}
{ucwords}
{$hello_world}<br />
{/ucwords}
<br />
Body end
</body>
</html>
Пример выведет:
Body begin
Hello World
Body end
Параметров наш блок не имеет, поэтому переменная $params не используется в нашей функции. Хотя параметры могли бы быть переданы в открывающем теге, как, например, в {foreach}. Переменная $content содержит результат интерпретации шаблона. Как раз эта переменная нам и нужна, чтобы обработать текст между тегами {ucwords} и {/ucwords}. Переменная $repeat дает нам возможность повторить вывод функции smarty_block_ucwords несколько раз. Если ей присвоить true без всяких условиев, то она бесконечное число раз будет выводить «Hello World».
Как сменить директорию плагинов или добавить свою
По умолчанию директория, в которой лежат файлы плагинов, называется «plugins» и находится в директории «smarty». Директорию можно сменить или добавить в массиве $plugins_dir объекта $smarty. При этом если мы указываем в этом массиве относительный путь, то смарти сначала будет искать относительно «smarty», если там не найдет – будет искать относительно текущей рабочей директории. Если и там не найдет – будет искать в include_path.
Причем, если мы зададим в $plugins_dir несколько путей, смарти будет искать файл плагина в порядке задания этих путей. Т.е. сначала в первом, потом – во втором и т.д.
Попробуем сменить путь к директории с плагинами:
<?
$smarty->plugins_dir = Array('allplugins'); // относительно директории smarty
?>
Или просто добавим путь к директории с нашими собственными плагинами:
<? $smarty->plugins_dir[] = 'myplugins'; // относительно директории smarty ?>
Резюме
Итак, мы рассмотрели, как писать плагины типов function, modifier и block в смарти. Я думаю, в больших проектах плагины на смарти бывают очень нужны, т.к. там чаще встречаются одни и те же участки шаблонов, которые неплохо было бы выделять в отдельные блоки кода. Тогда такой проект поддерживать уже легче.
Скачать примеры из статьи
Другие пишут:
- Smarty Plugins

Декабрь 18th, 2008
[...] Почему все именно так, написано здесь. [...]
Январь 21st, 2009
[...] Напишем очередной плагин
(кто забыл как это – читайте тут) [...]
Август 21st, 2009
Автор не подскажите про кодирование русских символов в smarty функцией {mailto}, может для этого написать плагин?
(скрытие email адреса)
Август 21st, 2009
Да, я как-то тоже сталкивался с этой проблемой – {mailto} не понимает русских символов. Для этого конечно нужно написать свой плагин с поддержкой той кодировки, с которой планируется работать. Можно переделать и имеющийся, но это будет некрасиво.
Сентябрь 9th, 2009
Расскажи, как получается, что плагины расположены не каждый в отдельном файле, а выполнены в качестве методов класса published\SC\html\scripts\modules\auxpages\class.auxpages.php, к примеру….