Пишем плагин для Смарти

Как мы уже говорили в предыдущей статье про 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 в смарти. Я думаю, в больших проектах плагины на смарти бывают очень нужны, т.к. там чаще встречаются одни и те же участки шаблонов, которые неплохо было бы выделять в отдельные блоки кода. Тогда такой проект поддерживать уже легче.

Скачать примеры из статьи

Другие пишут:





Читайте также:



7 Ответов на “Пишем плагин для Смарти”

  1. […] Почему все именно так, написано здесь. […]

  2. […] Напишем очередной плагин :)  (кто забыл как это - читайте тут) […]

  3. monolit66

    Автор не подскажите про кодирование русских символов в smarty функцией {mailto}, может для этого написать плагин?
    (скрытие email адреса)

  4. novice

    Да, я как-то тоже сталкивался с этой проблемой - {mailto} не понимает русских символов. Для этого конечно нужно написать свой плагин с поддержкой той кодировки, с которой планируется работать. Можно переделать и имеющийся, но это будет некрасиво.

  5. Расскажи, как получается, что плагины расположены не каждый в отдельном файле, а выполнены в качестве методов класса published\SC\html\scripts\modules\auxpages\class.auxpages.php, к примеру….

  6. А чтобы создать выпадающее меню и привязать его к админке для редактирования в ней, можно написать плагин?

  7. Коля

    Спасибо большое. Хорошо и доступно изложено.


© Copyright. . I-Novice. All Rights Reserved. Terms | Site Map