В этой статье мы подробно разберём, как создать собственный виджет для WordPress с нуля. Виджеты — это удобный инструмент для добавления функционала в боковые панели и другие области темы без необходимости править исходный код шаблона. Создание собственного виджета расширит возможности вашего сайта и позволит добавить именно тот функционал, который вам нужен.
Что такое виджеты в WordPress и зачем создавать свои
Виджеты — это небольшие блоки, которые можно размещать в заранее определённых областях темы, например, в сайдбаре, футере или других местах, поддерживающих виджеты. Стандартный WordPress уже поставляется с набором базовых виджетов: поиск, последние записи, категории, меню и т.д.
Однако часто стандартных виджетов недостаточно, и приходится искать плагины. Но если ни один из существующих плагинов не подходит, или хочется реализовать уникальный функционал, то логично создать свой собственный виджет. Это даст полный контроль над выводом и поведением блока.
Например, можно создать виджет для вывода произвольного текста с настройками, список избранных записей, форму подписки, персонализированное приветствие и многое другое.
Основы создания виджета WordPress: класс WP_Widget и его методы
Для создания виджета нужно создать класс, который наследуется от встроенного класса WP_Widget. В этом классе необходимо реализовать как минимум три метода:
__construct()— конструктор, где задаются название виджета и описание;widget($args, $instance)— метод, который выводит содержимое виджета на сайте;form($instance)— метод, который выводит форму настроек виджета в админке;update($new_instance, $old_instance)— метод для обработки и сохранения настроек виджета.
Также нужно зарегистрировать виджет, используя хук widgets_init.
Пример простого виджета с настройкой заголовка
Рассмотрим пример создания простого виджета, который выводит на сайт заголовок и произвольный текст, который можно задать в настройках.
class WPFreeCourses_Widget extends WP_Widget {
public function __construct() {
parent::__construct(
'wpfreecourses_widget',
__('WPFreeCourses: Простой виджет', 'wpfreecourses'),
array('description' => __('Простой виджет с заголовком и текстом', 'wpfreecourses'))
);
}
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'];
}
if (!empty($instance['content'])) {
echo '<p>' . esc_html($instance['content']) . '</p>';
}
echo $args['after_widget'];
}
public function form($instance) {
$title = !empty($instance['title']) ? $instance['title'] : '';
$content = !empty($instance['content']) ? $instance['content'] : '';
?>
<p>
<label for="<?php echo esc_attr($this->get_field_id('title')); ?>"><?php _e('Заголовок:', 'wpfreecourses'); ?></label>
<input class="widefat" id="<?php echo esc_attr($this->get_field_id('title')); ?>" name="<?php echo esc_attr($this->get_field_name('title')); ?>" type="text" value="<?php echo esc_attr($title); ?>">
</p>
<p>
<label for="<?php echo esc_attr($this->get_field_id('content')); ?>"><?php _e('Текст:', 'wpfreecourses'); ?></label>
<textarea class="widefat" id="<?php echo esc_attr($this->get_field_id('content')); ?>" name="<?php echo esc_attr($this->get_field_name('content')); ?>"><?php echo esc_textarea($content); ?></textarea>
</p>
<?php
}
public function update($new_instance, $old_instance) {
$instance = array();
$instance['title'] = sanitize_text_field($new_instance['title']);
$instance['content'] = sanitize_textarea_field($new_instance['content']);
return $instance;
}
}
function wpfreecourses_register_widget() {
register_widget('WPFreeCourses_Widget');
}
add_action('widgets_init', 'wpfreecourses_register_widget');Расширяем виджет: добавляем дополнительные настройки и вывод данных из базы
Теперь, когда базовый виджет готов, можно добавить более интересный функционал. Например, вывести список последних записей из определённой категории, заданной в настройках виджета.
Для этого в форме настроек добавим выпадающий список с категориями, в методе widget() сделаем запрос к базе и выведем заголовки.
Добавление выбора категории в настройки виджета
В методе form() получаем список категорий и создаём <select>:
public function form($instance) {
$title = !empty($instance['title']) ? $instance['title'] : '';
$category = !empty($instance['category']) ? $instance['category'] : 0;
$categories = get_categories(array('hide_empty' => false));
?>
<p>
<label for="<?php echo esc_attr($this->get_field_id('title')); ?>"><?php _e('Заголовок:', 'wpfreecourses'); ?></label>
<input class="widefat" id="<?php echo esc_attr($this->get_field_id('title')); ?>" name="<?php echo esc_attr($this->get_field_name('title')); ?>" type="text" value="<?php echo esc_attr($title); ?>">
</p>
<p>
<label for="<?php echo esc_attr($this->get_field_id('category')); ?>"><?php _e('Категория:', 'wpfreecourses'); ?></label>
<select class="widefat" id="<?php echo esc_attr($this->get_field_id('category')); ?>" name="<?php echo esc_attr($this->get_field_name('category')); ?>">
<option value="0" <?php selected($category, 0); ?>><?php _e('Все категории', 'wpfreecourses'); ?></option>
<?php foreach ($categories as $cat) : ?>
<option value="<?php echo esc_attr($cat->term_id); ?>" <?php selected($category, $cat->term_id); ?>><?php echo esc_html($cat->name); ?></option>
<?php endforeach; ?>
</select>
</p>
<?php
}Вывод последних постов из выбранной категории
В методе widget() делаем WP_Query с параметром категории и выводим список:
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'];
}
$category = !empty($instance['category']) ? intval($instance['category']) : 0;
$query_args = array(
'posts_per_page' => 5,
'post_status' => 'publish'
);
if ($category) {
$query_args['cat'] = $category;
}
$query = new WP_Query($query_args);
if ($query->have_posts()) {
echo '<ul>';
while ($query->have_posts()) {
$query->the_post();
echo '<li><a href="' . esc_url(get_permalink()) . '">' . esc_html(get_the_title()) . '</a></li>';
}
echo '</ul>';
wp_reset_postdata();
} else {
echo '<p>' . __('Записей не найдено.', 'wpfreecourses') . '</p>';
}
echo $args['after_widget'];
}Советы по безопасности и производительности при создании виджетов
При разработке виджетов очень важно учитывать безопасность и оптимизацию:
- Используйте функции очистки данных —
sanitize_text_field(),esc_html(),esc_attr(),esc_textarea()для обработки входных и выходных данных. - Минимизируйте количество запросов к базе. Кешируйте результаты, если виджет часто вызывается на странице.
- Избегайте выполнения тяжёлых операций в методе
widget(), чтобы не замедлять загрузку страницы. - Обрабатывайте ошибки и отсутствующие данные корректно, чтобы не ломать отображение сайта.
Пример кеширования вывода виджета
Можно использовать транзиенты для кеширования вывода. В widget() добавим:
public function widget($args, $instance) {
echo $args['before_widget'];
$cache_key = 'wpfreecourses_widget_cache_' . md5(serialize($instance));
$output = get_transient($cache_key);
if ($output === false) {
ob_start();
if (!empty($instance['title'])) {
echo $args['before_title'] . apply_filters('widget_title', $instance['title']) . $args['after_title'];
}
// вывод списка постов (как в предыдущем примере)
// ...
$output = ob_get_clean();
set_transient($cache_key, $output, 3600); // кеш 1 час
}
echo $output;
echo $args['after_widget'];
}Популярные плагины для расширения функционала виджетов в WordPress
Если создание собственного виджета кажется сложным или нужно быстро добавить популярный функционал, можно использовать готовые плагины:
- Widget Options — расширенные настройки виджетов, управление отображением по страницам и устройствам;
- Custom Sidebars — позволяет создавать неограниченное количество сайдбаров и назначать их на разные страницы;
- Black Studio TinyMCE Widget — виджет с визуальным редактором для добавления произвольного контента;
- SiteOrigin Widgets Bundle — набор разнообразных виджетов с возможностью кастомизации.
Эти плагины помогут быстро получить нужный функционал без программирования, однако создание собственного виджета — это всегда гибкий и эффективный способ контролировать поведение сайта.