В этой статье мы подробно разберём, как создать динамический виджет для WordPress с нуля. Виджеты — это ключевой инструмент для расширения функциональности сайта, позволяющий добавлять в боковые панели, футеры и другие области кастомный контент. Однако стандартные виджеты не всегда покрывают все задачи, поэтому умение создавать собственные динамические виджеты крайне полезно.
Что такое динамический виджет в WordPress и зачем он нужен
Динамический виджет — это виджет, содержимое которого может меняться в зависимости от различных условий: страницы, категории, пользовательских настроек и т.д. В отличие от статических виджетов, динамические более гибкие и позволяют создавать индивидуальный опыт для посетителей.
Например, вы можете сделать виджет, который показывает последние посты из определённой категории, либо отображает разные сообщения для авторизованных и неавторизованных пользователей. Такие возможности повышают удобство и полезность сайта.
Для создания подобных виджетов в WordPress используется класс WP_Widget. Мы создадим собственный класс, который расширит базовый функционал и добавит нужные возможности.
Регистрация и базовая структура виджета
Первый шаг — создать класс, который наследует WP_Widget и зарегистрировать его через хук widgets_init. Вот базовый шаблон:
class Wpbit_Dynamic_Widget extends WP_Widget {
public function __construct() {
parent::__construct(
'wpbit_dynamic_widget', // ID виджета
'WPBit Динамический Виджет', // Имя
array('description' => 'Динамический виджет с настройками')
);
}
public function widget($args, $instance) {
// Вывод виджета на фронтенде
}
public function form($instance) {
// Форма настроек в админке
}
public function update($new_instance, $old_instance) {
// Обработка сохранения настроек
}
}
function wpbit_register_dynamic_widget() {
register_widget('Wpbit_Dynamic_Widget');
}
add_action('widgets_init', 'wpbit_register_dynamic_widget');Этот код создаёт минимальный виджет, который можно расширять. В методах widget, form и update реализуется логика отображения, настройки и сохранения параметров соответственно.
Добавление настраиваемых параметров и динамического содержимого
Чтобы сделать виджет полезным, добавим несколько параметров, например, заголовок и категорию для вывода последних постов.
В методе form создадим поля для ввода заголовка и выбора категории:
public function form($instance) {
$title = !empty($instance['title']) ? $instance['title'] : '';
$category = !empty($instance['category']) ? $instance['category'] : '';
// Поле для заголовка
echo '<p><label for="' . $this->get_field_id('title') . '">Заголовок:</label>';
echo '<input class="widefat" id="' . $this->get_field_id('title') . '" '
. 'name="' . $this->get_field_name('title') . '" type="text" value="' . esc_attr($title) . '" /></p>';
// Выпадающий список категорий
$categories = get_categories();
echo '<p><label for="' . $this->get_field_id('category') . '">Категория:</label>';
echo '<select class="widefat" id="' . $this->get_field_id('category') . '" name="' . $this->get_field_name('category') . '">';
echo '<option value="">-- Выберите --</option>';
foreach ($categories as $cat) {
$selected = selected($category, $cat->term_id, false);
echo "<option value=\"{$cat->term_id}\" $selected>{$cat->name}</option>";
}
echo '</select></p>';
}В методе update обработаем сохранение параметров:
public function update($new_instance, $old_instance) {
$instance = array();
$instance['title'] = (!empty($new_instance['title'])) ? sanitize_text_field($new_instance['title']) : '';
$instance['category'] = (!empty($new_instance['category'])) ? intval($new_instance['category']) : '';
return $instance;
}В методе widget выведем заголовок и список последних постов из выбранной категории:
public function widget($args, $instance) {
echo $args['before_widget'];
if (!empty($instance['title'])) {
echo $args['before_title'] . apply_filters('widget_title', $instance['title']) . $args['after_title'];
}
$cat_id = !empty($instance['category']) ? $instance['category'] : 0;
if ($cat_id) {
$query = new WP_Query(array(
'cat' => $cat_id,
'posts_per_page' => 5,
'ignore_sticky_posts' => true
));
if ($query->have_posts()) {
echo '<ul>';
while ($query->have_posts()) {
$query->the_post();
echo '<li><a href="' . get_permalink() . '">' . get_the_title() . '</a></li>';
}
echo '</ul>';
wp_reset_postdata();
} else {
echo '<p>Посты не найдены.</p>';
}
} else {
echo '<p>Выберите категорию в настройках виджета.</p>';
}
echo $args['after_widget'];
}Расширение функциональности: условное отображение и кастомный HTML
Чтобы сделать виджет ещё более гибким, можно добавить условие на отображение, например, показывать виджет только на главной странице или только для авторизованных пользователей.
Добавим в настройки чекбоксы для условий отображения:
public function form($instance) {
// предыдущие поля
$show_on_home = !empty($instance['show_on_home']) ? (bool)$instance['show_on_home'] : false;
$show_for_logged_in = !empty($instance['show_for_logged_in']) ? (bool)$instance['show_for_logged_in'] : false;
echo '<p><input class="checkbox" type="checkbox" id="' . $this->get_field_id('show_on_home') . '" name="' . $this->get_field_name('show_on_home') . '" ' . checked($show_on_home, true, false) . ' />';
echo '<label for="' . $this->get_field_id('show_on_home') . '">Показывать только на главной странице</label></p>';
echo '<p><input class="checkbox" type="checkbox" id="' . $this->get_field_id('show_for_logged_in') . '" name="' . $this->get_field_name('show_for_logged_in') . '" ' . checked($show_for_logged_in, true, false) . ' />';
echo '<label for="' . $this->get_field_id('show_for_logged_in') . '">Показывать только для авторизованных пользователей</label></p>';
}
public function update($new_instance, $old_instance) {
$instance = array();
$instance['title'] = (!empty($new_instance['title'])) ? sanitize_text_field($new_instance['title']) : '';
$instance['category'] = (!empty($new_instance['category'])) ? intval($new_instance['category']) : '';
$instance['show_on_home'] = !empty($new_instance['show_on_home']) ? true : false;
$instance['show_for_logged_in'] = !empty($new_instance['show_for_logged_in']) ? true : false;
return $instance;
}В widget добавим проверку условий:
public function widget($args, $instance) {
if (!empty($instance['show_on_home']) && !is_front_page()) {
return; // Не показывать если не главная
}
if (!empty($instance['show_for_logged_in']) && !is_user_logged_in()) {
return; // Не показывать если пользователь не авторизован
}
// остальной вывод
}Также можно добавить в настройки поле для пользовательского HTML, который будет выводиться внутри виджета. Это расширит возможности настройки без правки кода.
Полезные плагины для работы с виджетами и примеры
Если вы не хотите писать виджеты с нуля, существуют полезные плагины, которые облегчают работу:
- Widget Options — расширенные настройки виджетов, включая условия отображения, стили и многое другое.
- Content Aware Sidebars — создание кастомных боковых панелей с условиями показа.
- PHP Code Widget — виджет для вставки PHP-кода напрямую в боковую панель.
Тем не менее, собственный виджет всегда даёт больше контроля и позволяет реализовать уникальные сценарии.
Заключение
Создание динамического виджета — это мощный инструмент для разработчика WordPress. Используя класс WP_Widget, вы можете добавить в свой сайт гибкие и настраиваемые элементы, которые улучшат взаимодействие с пользователями. В статье представлен полный пример с настройками, выводом постов и условной логикой, который можно легко расширять и адаптировать под свои задачи.