Выпуск 33. Виджеты и плагины
Как вы успели убедиться, виджеты, действительно интересны и удобны в использовании. Но, большинство нужной нам функциональности блога заключено всё-таки в плагинах. Было бы здорово перенести некоторые плагины в виджеты.
На самом деле эта задача не настолько сложна, как кажется на первый взгляд. Дело в том, что в самом виджете мы можем вызвать любую php-функцию, включая и ту, которую предоставляет плагин. Единственное, нам обязательно нужно проверять условие, что функция существует.
Какие плагины подходят для виджетизации
Теоретически мы можем сделать виджет для абсолютно любого плагина. Но здравый смысл показывает, что делать это нужно только для тех плагинов, которые нужно вручную прописывать в шаблоне.
Например в моем плагине Ушки код нужно указывать прямо в шаблоне.
Напомню, что с помощью ушек можно добавлять произвольный html-код, например счетчик или рекламный баннер.
Сам код ушки выглядит так:
<?php if (function_exists('show_ushka')) show_ushka('reklama', ''); ?>
В данном случае отобразится ушка и именем reklama.
Кодинг
Сам код получается до безобразия простой (functions.php):
<?php
function widget_maxsite_2() {
if (function_exists('show_ushka')) show_ushka('sidebar', '');
}
function widget_maxsite_2_options() {
echo 'Настроки ушки "sidebar" находятся в Настроки - Ушки';
}
register_sidebar_widget('Ушки 1', 'widget_maxsite_2');
register_widget_control('Ушки 1', 'widget_maxsite_2_options');
?>
Функция widget_maxsite_2 выводит ушку "sidebar". Естественно, саму ушку нужно предварительно создать.
Функцией widget_maxsite_2_options мы выводим в настройках виджета строку помощи.
Данный пример показывает, что в принципе совсем несложно добавить виджет для любого плагина. Тот код, который вы обычно прописываете вручную, теперь размещается с помощью виджета. Правда у данного подхода есть один недостаток: обычно функции имеют различные параметры, а в нашем случае (виджет) - нет. Поэтому есть смысл научиться делать настраиваемые виджеты.
Делаем настройки
Наш виджет можно снабдить одной настройкой, которая напрашивается сама по себе: название ушки. В прошлых номерах я уже рассматривал принцип создания настраиваемых виджетов, поэтому сейчас просто привожу код с комментариями.
function widget_maxsite_2() {
# проверяем есть ли функция ушки
if (function_exists('show_ushka'))
{
# считываем все наши опции
$options = get_option('widget_maxsite_2');
# если опция 'name' пустая, то назначаем ей имя 'sidebar'
$name = $options['name'] ? $options['name'] : 'sidebar';
# собственно сам вывод ушки
show_ushka($name, '');
}
}
function widget_maxsite_2_options() {
# определяем опции для этого виджета
$options = $newoptions = get_option('widget_maxsite_2');
# если было обновление
if ( $_POST['widget_maxsite_2_submit'] )
# обновляем настроку 'name'
$newoptions['name'] = stripslashes($_POST['widget_maxsite_2_name']);
# если новые опции не равны старым, то обновляем их
if ( $options != $newoptions ) {
$options = $newoptions;
update_option('widget_maxsite_2', $options);
}
# получили значение опции 'name'
$name = attribute_escape($options['name']);
# выводим поля формы
# обратите внимание на имена полей ввода
echo <<<EOF
Название ушки: <input id="widget_maxsite_2_name"
name="widget_maxsite_2_name"
type="text"
value="{$name}" />
<hr />Дополнительные настроки ушек находятся в Настроки - Ушки.
<input type="hidden"
id="widget_maxsite_2_submit"
name="widget_maxsite_2_submit"
value="1" />
EOF;
}
Этот код сложнее предыдущего, но при внимательном рассмотрении находим, что основная трудность - это имена полей и опций. Здесь нужно быть внимательным. Признаться за то время, которое я занимаюсь виджетами, мне так и не удалось найти оптимальное решение с именованием. Но какие-то полезные советы я всё-таки смогу дать.
Совет: "Автонаименование" полей формы и опций
При работе с виджетами нужно следить за тем, чтобы имена опций и имена полей формы были уникальными. При большом количестве виджетов очень легко запутаться, не говоря уже о сложных формах. Поэтому мы можем пойти на небольшую хитрость.
Поскольку уникальными должны быть еще и имена php-функций, то в качестве имен опций и префиксов полей мы можем использовать название самой функции. Правда есть один нюанс.
Для настраиваемого виджета мы используем две функции: первая это вывод виждета на странице сайта, и вторая - форма настроки в админ-панели. Так вот, нужно условиться по именам этих функций. Например для вывода формы настройки использовать имя функции вывода + "_options".
Пример:
widget_maxsite_2 widget_maxsite_2_options
Дальше просто. В PHP есть специальная константа __FUNCTION__, которая содержит имя выполняемой функции. То есть мы создаем отдельную переменную и присваиваем ей имя функции.
Эта переменная и будет нашим именем опций и префиксом полей. Примерно так (наша функция widget_maxsite_2_options):
...
$wd = __FUNCTION__;
$options = $newoptions = get_option($wd);
if ( $_POST["{$wd}_submit"] )
$newoptions['name'] = stripslashes($_POST["{$wd}_name"]);
...
Название ушки: <input id="{$wd}_name"
name="{$wd}_name"
type="text"
value="{$name}" />
...
Как видите этот код читается гораздо легче и ошибиться будет уже сложней.
В функции вывода (widget_maxsite_2) нам придется изменить только одну строчку:
$options = get_option(__FUNCTION__ . '_options');
То есть мы дописываем к имени функции (наша widget_maxsite_2) "_options".
Потому что название опций мы делали в функции widget_maxsite_2_options (название опций = названию функции)!
Совет: Вспомогательная функция для формирования текстового поля
Этот совет пригодится тем, кто делает много виджетов. Вы наверное обратили внимание, что по-сути, формы разных виджетов повторяются. Меняется только название полей (в тэге <input>). Поэтому можно несколько упростить себе задачу с помощью дополнительной функции, которая будет возвращать уже готовый html-код.
function maxsite_make_text ($name = '', $value = ''){
$out = '<input id="'
. $name
. '" name="'
. $name
. '" type="text" value="'
. $value
. '" />';
return $out;
}
Первым параметром мы передаем name (id) поля, вторым - его значение. На выходе получаем уже готовый html-код.
Вот пример использования:
$title = attribute_escape($options['title']);
$title = maxsite_make_text('maxsite_widget_title', $title);
...
echo <<<EOF
Заголовок: {$title}
...
Совет: Вспомогательная функция для формирования checkbox
Функция аналогична предыдущей, только используется для формирования чекбоксов.
function maxsite_make_checkbox ($name = '', $chek = ''){
$out = '<input class="checkbox" type="checkbox" '
. $chek
. ' id="'
. $name
. '" name="'
. $name
. '" />';
return $out;
}
Пример использования:
$link_all = $options['link_all'] ? 'checked="checked"' : '';
$link_all = maxsite_make_checkbox('maxsite_widget_link_all', $link_all);
...
echo <<<EOF
<br />{$link_all} Показывать ссылку
...
Совет: собственные виджеты в виде плагина
Этот совет пригодится тем, кто использует собственные виджеты для своих шаблонов. В этом случае код виджетов удобней сделать в виде плагина и он будет един для всех шаблонов.
По сути мы просто переносим виджеты из functions.php в отдельный файл плагина. Вот так это выглядит у меня.
Файл-плагин maxsite-widgets.php:
<?php /* Plugin Name: MaxSite-widget Version: 1.2 Plugin URI: http://maxsite.org/ Description: Виджеты Author: Максим (http://maxsite.org/) Author URI: http://maxsite.org/ */ # инициализация и регистрация всех виджетов function widget_maxsite_init() { # удалим все стандартные виджеты remove_action('init', 'wp_widgets_init', 1); ... register_widget_control и register_sidebar_widget всех моих виджетов, которые располагаются в этом же файле ниже. ... } дальше пошли функции виджетов
Файл functions.php (шаблонный):
# регистрация сайдбара
register_sidebar(array(
'name' => 'Первая колонка',
'before_widget' => '', 'after_widget' => '',
'before_title' => '', 'after_title' => ''));
# инициализация
if (function_exists('widget_maxsite_init')) widget_maxsite_init();
После активации плагина, виджеты станут доступны всем вашим шаблонам.
В заключении хотелось бы сказать, что тема виджетов очень обширная. Скорее всего нас ожидает развитие их в будущих версиях WordPress, а также возможно появятся наработки, позволящие использовать виджеты в разных частях шаблона. Сейчас это уже можно делать, но сам механизм должет быть еще отлажен. Со временем, наверное, можно будет настраивать свой блог как конструктор Лего.
Постоянная ссылка: http://maxsite.org/?p=270
Версия для печати
