Пишем плагин для Смарти
Как мы уже говорили в предыдущей статье про 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 в смарти. Я думаю, в больших проектах плагины на смарти бывают очень нужны, т.к. там чаще встречаются одни и те же участки шаблонов, которые неплохо было бы выделять в отдельные блоки кода. Тогда такой проект поддерживать уже легче.
Скачать примеры из статьи
Другие пишут:
- Плагин Spaw для Smarty
- Smarty Plugins
[…] Почему все именно так, написано здесь. […]
[…] Напишем очередной плагин (кто забыл как это - читайте тут) […]
Автор не подскажите про кодирование русских символов в smarty функцией {mailto}, может для этого написать плагин?
(скрытие email адреса)
Да, я как-то тоже сталкивался с этой проблемой - {mailto} не понимает русских символов. Для этого конечно нужно написать свой плагин с поддержкой той кодировки, с которой планируется работать. Можно переделать и имеющийся, но это будет некрасиво.
Расскажи, как получается, что плагины расположены не каждый в отдельном файле, а выполнены в качестве методов класса published\SC\html\scripts\modules\auxpages\class.auxpages.php, к примеру….
А чтобы создать выпадающее меню и привязать его к админке для редактирования в ней, можно написать плагин?
Спасибо большое. Хорошо и доступно изложено.