Добавление произвольного виджета

В директории с плагинами WordPress расположено несколько сотен различных плагинов и виджетов. Несмотря на это, бывают ситуации, когда даже такого огромного набора средств недостаточно. В таком случае вам понадобится создать собственный виджет или плагин, решающий определенную проблему, что является весомым аргументом в пользу дальнейшей дистрибьюции темы, особенно если созданные виджеты завязаны на реализации каких-либо уникальных возможностей или функций.

Традиционно, существует два различных способа добавления созданных виджетов к теме. Первый способ основан на внесении новой функции в файл functions.php. Этот способ мы уже использовали ранее для добавления необходимой нам функциональности. Как мы успели заметить, данный способ приводит к быстрому разрастанию файла functions.php, что значительно усложняет его дальнейшее редактирование, однако использование комментариев и разбиения на участки позволяет решить возникшую проблему. Второй способ добавления виджетов к теме заключается в создании плагина под каждый новый виджет. Этот способ также не лишен своих недостатков: созданный плагин будет существовать отдельно от темы, что, естественно, добавит несколько новых шагов к процессу установки темы. Мы же хотим, чтобы тема была настолько проста в использовании насколько это возможно, следовательно, мы постараемся избежать лишней работы. К счастью, в фреймворке Thematic предусмотрено довольно инновационное встроенное решение для виджетов, которое значительно упрощает процесс их создания и управления — функция, которая ищет папку с названием widgets в дочерней теме и добавляет любые виджеты без каких-либо дополнительных действий со стороны разработчика. Эта возможность также означает, что созданные виджеты будут автоматически распространяться вместе с дочерней темой, что очень удобно, поскольку это позволяет исключить шаги по установке/активации дополнительных плагинов. Еще один приятный бонус использования папки widgets — вы можете организовать каждый виджет в виде отдельного PHP файла.

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

Введение в API виджетов

Для того чтобы создать новый виджет в WordPress, нам необходимо расширить стандартный класс виджетов (WP_Widget). Если вы не знакомы с объектно-ориентированным программированием, не стоит переживать: в процессе разработки виджетов WordPress мы лишь поверхностно затронем ООП. Каждый класс виджетов обладает четырьмя стандартными функциями: конструктором, а также функциями widget, update и form.

Для начала взглянем на пустую оболочку для нового виджета:

class My_Widget extends WP_Widget {
function My_Widget() {
// this is a constructor, where each new instance of your widget gets built
}function form($instance) {
// this generates the widget options form which you see
// in the widgets section in the admin
}function update($new_instance, $old_instance) {
// this handles the submission of the options form to
// update the widget options
}function widget($args, $instance) {
// the most important function: this one handles actually outputting
// the widget's content to the theme
}
}

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

register_widget ('My_Widget');

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

Создание виджета

Приступим к созданию нашего первого произвольного виджета. Создадим папку widgets в нашей дочерней теме и добавим к ней новый PHP файл. Назовем его author-data.php. Объявим класс Author_Data_Widget вместе с четырьмя необходимыми функциями и вызовем register_widget:

<?phpclass Author_Data_Widget extends WP_Widget {
function Author_Data_Widget() {}  function form($instance) {}function update($new_instance, $old_instance) {}

function widget($args, $instance) {

}
}

register_widget('Author_Data_Widget');

?>

Наша первая задача состоит в том, чтобы создать конструктор. В канонической форме записи конструктор имеет следующий вид:

function My_Widget() {
$this-<WP_Widget($id, $name, $widget_ops, $control_ops);
}

Инструкция ($this->WP_Widget) описывает процесс создания нового экземпляра виджета. Параметр $id используется для внутреннего обращения к созданному виджету, $name — имя, которое отображается в панели виджетов, $widget_ops — массив, включающий в себя описание виджета, которое будет показано в панели администратора, $control_ops — необязательный параметр, не требуемый для большинства виджетов (мы не будем пока что его рассматривать). Запишем данную функцию к нашему виджету:

function Author_Data_Widget() {
$widget_ops = array(
'description' =< 'A widget that displays author info on single posts.'
);
$this-<WP_Widget('author_data', 'Author Data', $widget_ops);
}

Даже с одной этой функцией мы сможем увидеть наш виджет во внутреннем интерфейсе.

Однако, если мы переместим наш виджет в одну из областей виджетов, то увидим, что у него нет никаких настроек.

Сделаем так, чтобы пользователи могли определять заголовок виджета. Для этого нам придется внести некоторые изменения в функции form и update. Начнем с метода form.

К счастью, WordPress способен обрабатывать создание элемента form; все, что мы должны сделать, это определить элементы label и input для каждой из настроек. Эти элементы для корректной работы должны иметь атрибуты id и name; WordPress помогает нам и в этом случае, поскольку виджет имеет функции get_field_id и get_field_name. Ниже приведен пример, как может выглядеть наша простая форма:

function form($instance) {
$title = esc_attr($instance['title']);
?>
<p>
<label for="<?php echo $this->get_field_id('title'); ?>">Title:
<input
id="<?php echo $this->get_field_id('title'); ?>"
name="<?php echo $this->get_field_name('title'); ?>"
type="text"
value="<?php echo attribute_escape($title); ?>" />
</label>
</p>
<?php
}

Функция получает переменную $instance, которая представляет текущий виджет с определенным набором настроек. Первое, что мы делаем, это извлекаем переменную $title из $instance. Затем мы создаем поле формы, используя $this->get_field_id и $this->get_field_name для установки атрибутов поля id и name.

После того как форма будет представлена, WordPress перейдет к функции update, которая позволяет сохранить изменения, внесенные пользователем в поля формы. Давайте взглянем на данную функцию:

function update($new_instance, $old_instance) {
$instance = $old_instance;
$instance['title'] = strip_tags($new_instance['title']);return $instance;
}

Функция update работает несколько иначе: она получает два параметра, первый из которых содержит новый виджет, включающий настройки, представленные в форме, а второй — содержит старый виджет с предыдущими настройками. Таким образом, мы должны захватить заголовок из $new_instance и использовать его для установки заголовка в нашем экземпляре. Чтобы избежать беспорядка, мы сохранили $old_instance в новую переменную, названную $instance, которая и будет хранить наш новый заголовок. Затем мы возвращаем $instance и WordPress производит обновление виджета с теми настройками, которые мы установили.

Если ваша форма имеет более чем одно поле, вам придется повторить заданный процесс ля каждой настройки, которая требует установки. Вы можете включать в функцию update столько логики, сколько вам понадобится. Если вы, к примеру, хотите отбросить некоторые настройки (на основании проверки условия), все, что вам понадобится сделать, это возвратить false, вследствие чего виджет не будет обновлен.

Теперь, когда мы создали собственную форму настроек, вернемся к панели администратора и проведем небольшое тестирование формы: перетащим виджет Author Data в одну из областей виджетов. Вы должны увидеть новое поле, позволяющее устанавливать заголовок виджета:

Таким образом, мы имеем три функции: конструктор, form и update, каждая из которых выполняет обработку нашей формы виджета.

Посмотрим на функцию, которая позволяет вывести на экран наш виджет:

function widget($args, $instance) {
extract($args, EXTR_SKIP);if (is_single()) {echo $before_widget;
$title = apply_filters('widget_title', $instance['title']);

if ( !empty( $title ) ) { echo $before_title . $title . $after_title; };
echo '<div>';
echo get_avatar(get_the_author_meta('user_email'), 150);
echo '<h4>' . the_author_meta('display_name') . '</h4>';
// Is there an author description?
if (get_the_author_meta('description')) {
echo '<div><p>'
. get_the_author_meta('description')
. '</p></div>';
}
echo '</div>';
echo $after_widget;
}
}

Функция получает два параметра: $args — массив аргументов, используемых всеми виджетами в теме. Эти аргументы уже знакомы вам: before_title, after_title, before_widget, и after_widget. Второй параметр — это $instance, который содержит набор настроек вашего виджета. В нашем случае это только заголовок.

Теперь, когда мы записали все необходимые функции, виджет должен правильно выводить на экран информацию об авторе на страницах с отдельными записями. Ниже приведен полный листинг файла author-data.php:

<?phpclass Author_Data_Widget extends WP_Widget {
function Author_Data_Widget() {
$widget_ops = array(
'description' => 'A widget that displays author info on single posts.'
);
$this->WP_Widget('author_data', 'Author Data', $widget_ops);
}

function form($instance) {
$title = esc_attr($instance['title']);
?>
<p>
<label for="<?php echo $this->get_field_id('title'); ?>">Title:
<input
id="<?php echo $this->get_field_id('title'); ?>"
name="<?php echo $this->get_field_name('title'); ?>"
type="text"
value="<?php echo attribute_escape($title); ?>" />
</label>
</p>
<?php
}

function update($new_instance, $old_instance) {
$instance = $old_instance;
$instance['title'] = strip_tags($new_instance['title']);

return $instance;
}

function widget($args, $instance) {
extract($args, EXTR_SKIP);

if (is_single()) {

echo $before_widget;
$title = apply_filters('widget_title', $instance['title']);

if (!empty($title)) { echo $before_title . $title . $after_title; };
echo '<div>';
echo get_avatar(get_the_author_meta('user_email'), 150);
echo '<h4>' . the_author_meta('display_name') . '</h4>';

// Is there an author description?
if (get_the_author_meta('description')) {
echo '<div><p>'
. get_the_author_meta('description')
. '</p></div>';
}
echo '</div>';
echo $after_widget;
}
}
}
register_widget('Author_Data_Widget');

?>

Блог про WordPress
Добавить комментарий

Получать новые комментарии по электронной почте.