В WordPress виджеты — это удобный способ добавить кастомный функционал в боковые панели и другие области сайта. Но часто стандартных виджетов недостаточно, и возникает задача создать собственный динамический виджет, который будет выводить данные в зависимости от контекста, пользовательских настроек или других факторов.
Что такое динамический виджет в WordPress и почему он нужен
Динамический виджет — это виджет, который изменяет свое содержимое в зависимости от условий, например, текущей страницы, категории, роли пользователя или параметров, введенных в админке. Такой виджет позволяет сделать сайт более интерактивным и персонализированным.
Преимущества динамического виджета:
- Гибкость вывода контента.
- Улучшение удобства пользователя.
- Расширение функционала без установки лишних плагинов.
Далее мы разберем, как создать такой виджет самостоятельно с нуля, используя стандартные методы WordPress.
Регистрация собственного виджета: базовый каркас
Для создания виджета нужно создать класс, который наследует WP_Widget, и реализовать несколько методов:
__construct()— инициализация виджета.widget()— вывод виджета на сайте.form()— форма настроек в админке.update()— сохранение настроек.
Пример базового класса с префиксом wpeditor_:
class wpeditor_Dynamic_Widget extends WP_Widget {
public function __construct() {
parent::__construct(
'wpeditor_dynamic_widget',
'Динамический виджет WPEditor',
array('description' => 'Пример динамического виджета')
);
}
public function widget($args, $instance) {
echo $args['before_widget'];
echo $args['before_title'] . apply_filters('widget_title', $instance['title']) . $args['after_title'];
// Здесь будет динамический вывод
echo $args['after_widget'];
}
public function form($instance) {
$title = !empty($instance['title']) ? $instance['title'] : 'Динамический виджет';
?>
<p>
<label for="<?php echo $this->get_field_id('title'); ?>">Заголовок:</label>
<input class="widefat" id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" type="text" value="<?php echo esc_attr($title); ?>">
</p>
<?php
}
public function update($new_instance, $old_instance) {
$instance = array();
$instance['title'] = (!empty($new_instance['title'])) ? strip_tags($new_instance['title']) : '';
return $instance;
}
}
function wpeditor_register_dynamic_widget() {
register_widget('wpeditor_Dynamic_Widget');
}
add_action('widgets_init', 'wpeditor_register_dynamic_widget');Этот код регистрирует простой виджет с одним полем заголовка.
Добавление динамического содержимого в виджет
Теперь сделаем так, чтобы содержимое виджета менялось в зависимости от текущей категории записи, например, выводить приветствие и количество постов в категории.
В методе widget() заменим комментарий на следующий код:
public function widget($args, $instance) {
echo $args['before_widget'];
echo $args['before_title'] . apply_filters('widget_title', $instance['title']) . $args['after_title'];
if (is_single()) {
$categories = get_the_category();
if (!empty($categories)) {
$cat = $categories[0];
$cat_name = esc_html($cat->name);
$cat_id = $cat->term_id;
$cat_count = $cat->count;
echo "<p>Вы читаете статью из категории: <strong>{$cat_name}</strong></p>";
echo "<p>Всего статей в этой категории: <strong>{$cat_count}</strong></p>";
} else {
echo "<p>Категория не определена</p>";
}
} else {
echo "<p>Просматривается не статья.</p>";
}
echo $args['after_widget'];
}Таким образом, виджет покажет полезную информацию, связанную с текущим контекстом.
Расширение виджета: добавление дополнительных настроек
Для удобства пользователя добавим еще одно поле в админку виджета — выбор типа информации для вывода: приветствие, количество постов или дата последнего обновления категории.
Изменим метод form() следующим образом:
public function form($instance) {
$title = !empty($instance['title']) ? $instance['title'] : 'Динамический виджет';
$info_type = !empty($instance['info_type']) ? $instance['info_type'] : 'greeting';
?>
<p>
<label for="<?php echo $this->get_field_id('title'); ?>">Заголовок:</label>
<input class="widefat" id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" type="text" value="<?php echo esc_attr($title); ?>">
</p>
<p>
<label for="<?php echo $this->get_field_id('info_type'); ?>">Тип информации:</label>
<select class="widefat" id="<?php echo $this->get_field_id('info_type'); ?>" name="<?php echo $this->get_field_name('info_type'); ?>">
<option value="greeting" <?php selected($info_type, 'greeting'); ?>>Приветствие</option>
<option value="count" <?php selected($info_type, 'count'); ?>>Количество постов</option>
<option value="last_update" <?php selected($info_type, 'last_update'); ?>>Дата последнего обновления</option>
</select>
</p>
<?php
}И в методе update() добавим сохранение этого поля:
public function update($new_instance, $old_instance) {
$instance = array();
$instance['title'] = (!empty($new_instance['title'])) ? strip_tags($new_instance['title']) : '';
$instance['info_type'] = (!empty($new_instance['info_type'])) ? strip_tags($new_instance['info_type']) : 'greeting';
return $instance;
}Теперь адаптируем метод widget() для вывода выбранной информации:
public function widget($args, $instance) {
echo $args['before_widget'];
echo $args['before_title'] . apply_filters('widget_title', $instance['title']) . $args['after_title'];
if (is_single()) {
$categories = get_the_category();
if (!empty($categories)) {
$cat = $categories[0];
$cat_name = esc_html($cat->name);
$cat_id = $cat->term_id;
$cat_count = $cat->count;
switch ($instance['info_type']) {
case 'greeting':
echo "<p>Добро пожаловать в категорию: <strong>{$cat_name}</strong></p>";
break;
case 'count':
echo "<p>Всего постов в категории <strong>{$cat_name}</strong>: <strong>{$cat_count}</strong></p>";
break;
case 'last_update':
$last_post_date = get_last_post_date_in_category($cat_id);
echo "<p>Последнее обновление категории <strong>{$cat_name}</strong>: <strong>{$last_post_date}</strong></p>";
break;
}
} else {
echo "<p>Категория не определена</p>";
}
} else {
echo "<p>Просматривается не статья.</p>";
}
echo $args['after_widget'];
}
// Вспомогательная функция для получения даты последнего поста в категории
function get_last_post_date_in_category($cat_id) {
$args = array(
'category' => $cat_id,
'posts_per_page' => 1,
'orderby' => 'modified',
'order' => 'DESC',
'fields' => 'post_date',
);
$posts = get_posts($args);
if (!empty($posts)) {
return date_i18n(get_option('date_format'), strtotime($posts[0]->post_date));
}
return 'Нет данных';
}Примеры полезных плагинов для кастомных виджетов
Если вы хотите создавать виджеты без программирования, можно обратить внимание на плагины:
- Widget Options — расширяет возможности стандартных виджетов, позволяет задавать условия отображения, видимость по ролям, устройствам.
- Custom Sidebars — дает возможность создавать собственные боковые панели и выводить их на определенных страницах.
- SiteOrigin Widgets Bundle — набор виджетов с гибкими настройками для визуального конструкторa.
Однако для полной кастомизации и динамичности лучше писать свои виджеты на PHP, как показано выше.
Заключение
Создание динамического виджета — важный навык для разработчика WordPress. Такой виджет позволяет вывести релевантную и полезную информацию, улучшая взаимодействие пользователя с сайтом. В этой статье вы увидели, как создать базовый виджет, добавить настройки в админке и вывести контекстно-зависимый контент с помощью кода. Используйте эти знания для расширения функционала ваших проектов на WordPress.