В этой статье мы поговорим о том, как создать свой собственный виджет для вашего сайта на WordPress. Виджеты — это мощный инструмент для улучшения функциональности сайта и предоставления дополнительной информации вашим посетителям. Это может быть свежие комментарии, новые посты, баннер и другие полезности сайта.
Стандартные виджеты, предоставляемые WordPress, могут быть ограничены в функциональности и дизайне. Создавая свой собственный виджет, вы освобождаетесь от ограничений и можете реализовать любую свою идею. Это особенно актуально для сайтов, где требуется уникальный функционал, подстроенный под конкретные цели.
Из чего состоит виджет
Виджет включает в себя пять основных параметров, обеспечивающих его работу и взаимодействие с сайтом. Для примера создадим простой виджет, который будет состоять из поля «Название» и поле «Текст».
1. Класс виджета
Первым делом создаем класс Simple_Widget
, который наследует базовый класс WP_Widget
. Это класс Simple_Widget
— произвольный. Он может любым, но уникальным. Последующие части кода будут дополнять друг друга, и в конечном итоге, то есть на пятом шаге, получится готовый виджет, который можно проверить, вставив весь код в ваш файл functions.php. Только в начале кода удалите тег <?php
или подключайте виджет через функцию require_once
. О ней подробнее будет ниже.
<?php // Создаем класс для нашего виджета class Simple_Text_Widget extends WP_Widget { // Конструктор класса public function __construct() { parent::__construct( 'simple_text_widget',// Уникальный ID виджета 'Простой виджет',// Название виджета array('description' => 'Это простой текстовый виджет для вывода произвольного текста.') ); } //продолжение... }
В конструкторе задаем уникальный ID
. Если этого не сделать, WordPress автоматически присваивает ему уникальный ID на основе названия виджета. Это обеспечивает уникальность виджетов на сайте и позволяет избежать конфликтов. Дальше заполните название и описание. Эта информация будит видна в панели виджетов.
2. Функция form. Настройка виджета
Функция form
выводим форму настройки виджета в админ-панели. Она может содержать любой тип: текстовые поля, списки выбора, чекбоксы и т.д. В данном примере находятся два поля:input
— переменная $title
и textarea
— переменная $text
.
<?php // Создаем класс для нашего виджета class Simple_Text_Widget extends WP_Widget { // Конструктор класса public function __construct() { parent::__construct( 'simple_text_widget',// Уникальный ID виджета 'Простой виджет',// Название виджета array('description' => 'Это простой текстовый виджет для вывода произвольного текста.') ); } // Функция для вывода формы настройки виджета в админ-панели public function form($instance) { $title = !empty($instance['title']) ? $instance['title'] : ''; $text = !empty($instance['text']) ? $instance['text'] : ''; ?> <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('text'); ?>">Текст:</label> <textarea class="widefat" rows="10" id="<?php echo $this->get_field_id('text'); ?>" name="<?php echo $this->get_field_name('text'); ?>"><?php echo esc_attr($text); ?></textarea> </p> <?php } //продолжение... }
3. Функции update. Сохранение настроек
Функция update
в виджетах WordPress используется для сохранения настроек виджета после их редактирования. Когда пользователь изменяет настройки виджета и сохраняет изменения, данные формы виджета передаются на сервер и обрабатываются функцией update
. Эта функция принимает два аргумента: новые значения параметров виджета $new_instance
и предыдущие значения — $old_instance
.
<?php // Создаем класс для нашего виджета class Simple_Text_Widget extends WP_Widget { // Конструктор класса public function __construct() { parent::__construct( 'simple_text_widget',// Уникальный ID виджета 'Простой виджет',// Название виджета array('description' => 'Это простой текстовый виджет для вывода произвольного текста.') ); } // Функция для вывода формы настройки виджета в админ-панели public function form($instance) { $title = !empty($instance['title']) ? $instance['title'] : ''; $text = !empty($instance['text']) ? $instance['text'] : ''; ?> <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('text'); ?>">Текст:</label> <textarea class="widefat" rows="10" id="<?php echo $this->get_field_id('text'); ?>" name="<?php echo $this->get_field_name('text'); ?>"><?php echo esc_attr($text); ?></textarea> </p> <?php } // Функция для сохранения настроек виджета public function update($new_instance, $old_instance) { $instance = array(); $instance['title'] = !empty($new_instance['title']) ? strip_tags($new_instance['title']) : ''; $instance['text'] = !empty($new_instance['text']) ? $new_instance['text'] : ''; return $instance; } // продолжение... }
4. Функция widget. Вывод содержимого
Внутри функции widget
, вы можете использовать содержимое $args
и $instance
для определения того, что именно нужно отобразить в виджете.
$args
— это массив с информацией о текущем виджете и его обертке (HTML-код до и после виджета).
$instance
— это массив с сохраненными пользовательскими настройками виджета.
<?php // Создаем класс для нашего виджета class Simple_Text_Widget extends WP_Widget { // Конструктор класса public function __construct() { parent::__construct( 'simple_text_widget',// Уникальный ID виджета 'Простой виджет',// Название виджета array('description' => 'Это простой текстовый виджет для вывода произвольного текста.') ); } // Функция для вывода формы настройки виджета в админ-панели public function form($instance) { $title = !empty($instance['title']) ? $instance['title'] : ''; $text = !empty($instance['text']) ? $instance['text'] : ''; ?> <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('text'); ?>">Текст:</label> <textarea class="widefat" rows="10" id="<?php echo $this->get_field_id('text'); ?>" name="<?php echo $this->get_field_name('text'); ?>"><?php echo esc_attr($text); ?></textarea> </p> <?php } // Функция для сохранения настроек виджета public function update($new_instance, $old_instance) { $instance = array(); $instance['title'] = !empty($new_instance['title']) ? strip_tags($new_instance['title']) : ''; $instance['text'] = !empty($new_instance['text']) ? $new_instance['text'] : ''; return $instance; } // Функция для вывода содержимого виджета на странице public function widget($args, $instance) { $title = apply_filters('widget_title', $instance['title']); $text = $instance['text']; echo $args['before_widget']; if (!empty($title)) { echo $args['before_title'] . $title . $args['after_title'];//вывод названия виджета } echo '<p>' . $text . '</p>';//вывод содержимого echo $args['after_widget']; } }
5. Регистрация виджета
С помощью пользовательской функции function register_simple_text_widget()
мы регистрируем виджет Simple_Text_Widget
. Внутри этой функции используется функция register_widget()
, которая регистрирует виджет для использования в WordPress.
<?php // Создаем класс для нашего виджета class Simple_Text_Widget extends WP_Widget { // Конструктор класса public function __construct() { parent::__construct( 'simple_text_widget',// Уникальный ID виджета 'Простой виджет',// Название виджета array('description' => 'Это простой текстовый виджет для вывода произвольного текста.') ); } // Функция для вывода формы настройки виджета в админ-панели public function form($instance) { $title = !empty($instance['title']) ? $instance['title'] : ''; $text = !empty($instance['text']) ? $instance['text'] : ''; ?> <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('text'); ?>">Текст:</label> <textarea class="widefat" rows="10" id="<?php echo $this->get_field_id('text'); ?>" name="<?php echo $this->get_field_name('text'); ?>"><?php echo esc_attr($text); ?></textarea> </p> <?php } // Функция для сохранения настроек виджета public function update($new_instance, $old_instance) { $instance = array(); $instance['title'] = !empty($new_instance['title']) ? strip_tags($new_instance['title']) : ''; $instance['text'] = !empty($new_instance['text']) ? $new_instance['text'] : ''; return $instance; } // Функция для вывода содержимого виджета на странице public function widget($args, $instance) { $title = apply_filters('widget_title', $instance['title']); $text = $instance['text']; echo $args['before_widget']; if (!empty($title)) { echo $args['before_title'] . $title . $args['after_title'];//вывод названия виджета } echo '<p>' . $text . '</p>'; //вывод текста echo $args['after_widget']; } } // Регистрируем наш виджет function register_simple_text_widget() { register_widget('Simple_Text_Widget'); } add_action('widgets_init', 'register_simple_text_widget');
Результат
Это была последняя часть кода. Теперь мы можем проверить, что получилось в итоге. Главное не забывайте про тег <?php
в начале кода. Скопируйте весь код из пятого шага, удалите тег PHP и в ставьте в файл functions.php.
Зайдите в админ-панел во вкладку «Внешний вид — Виджеты». Найдите наш виджет под названием «Простой виджет» и перетащите в видемую область. Заполните все его поля и проверьте его отображение на сайте.
Кастомный виджет WordPress с выводом новых записей
А теперь давайте создадим более сложный и функциональный виджет для WordPress. Новый виджет будет выводить свежие посты из любой категории или всех сразу. Вы сможете настроить его параметры, такие как показ миниатюры, даты и возможность скрыть прилепленные записи.
- Создайте файл-php и поместите в него ниже представленный код
- Сохраните файл под названием «ws-post-widget.php»
- Загрузите его на сайт в вашу тему оформления, конечно в дочернюю.
- Откройте файл functions.php дочерней темы и подключите ранее созданный файл таким образом:
//виджет вывода постов require_once (get_stylesheet_directory() . '/ws-post-widget.php' );
Код виджета
<?php /** Вывовд новых постов */ class wordsmall_widget_post extends WP_Widget { /* Функция регистрации виджета*/ function __construct() { parent::__construct( 'ws_widget_post', // Базовый идентификатор виджета. Должен быть уникальным. 'Последние записи WordSmall', // название виджета в админке array( 'description' => 'Отображаение последних записей из выбранной категории' ) //Описание виджетв ); } /** Панель настроек виджета в админке */ public function form( $instance ) { $defaults = array( 'title' => 'Последние записи', 'category' => 'all', 'number_posts' => 5, 'sticky_posts' => true, ); $instance = wp_parse_args( (array) $instance, $defaults ); $number_posts = isset( $instance['number_posts'] ) ? absint( $instance['number_posts'] ) : 3; $show_thumbnails = isset( $instance['show_thumbnails'] ) ? (bool) $instance['show_thumbnails'] : false; $show_date = isset( $instance['show_date'] ) ? (bool) $instance['show_date'] : false; ?> <p> <label for="<?php echo $this->get_field_id( 'title' ); ?>">Название:</label> <input type="text" class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" value="<?php echo esc_attr($instance['title']); ?>"/> </p> <p> <label>Выбор категории:</label> <?php wp_dropdown_categories( array( 'name' => $this->get_field_name('category'), 'selected' => $instance['category'], 'show_option_all' => 'Все категории' ) ); ?> </p> <p> <label for="<?php echo $this->get_field_id( 'number_posts' ); ?>">Количество постов:</label> <input type="text" id="<?php echo $this->get_field_id( 'number_posts' ); ?>" name="<?php echo $this->get_field_name( 'number_posts' );?>" value="<?php echo $number_posts; ?>" size="3"/> </p> <p> <input type="checkbox" <?php checked( $instance['sticky_posts'], true ) ?> class="checkbox" id="<?php echo $this->get_field_id('sticky_posts'); ?>" name="<?php echo $this->get_field_name('sticky_posts'); ?>" /> <label for="<?php echo $this->get_field_id('sticky_posts'); ?>">Скрыть прилепленные записи.</label> </p> <p> <input id="<?php echo $this->get_field_id( 'show_thumbnails' ); ?>" name="<?php echo $this->get_field_name( 'show_thumbnails' ); ?>" type="checkbox" <?php checked( $show_thumbnails ); ?>> <label for="<?php echo $this->get_field_id( 'show_thumbnails' ); ?>">Показать миниатюры.</label> </p> <p> <input id="<?php echo $this->get_field_id( 'show_date' ); ?>" name="<?php echo $this->get_field_name( 'show_date' ); ?>" type="checkbox" <?php checked( $show_date ); ?>> <label for="<?php echo $this->get_field_id( 'show_date' ); ?>">Показать дату.</label> </p> <?php } /* Сохранение настроек при их обновлении */ public function update( $new_instance, $old_instance ) { $instance = $old_instance; $instance[ 'title' ] = sanitize_text_field( $new_instance[ 'title' ] ); $instance[ 'category' ] = absint( $new_instance[ 'category' ] ); $instance[ 'number_posts' ] = (int)$new_instance[ 'number_posts' ]; $instance[ 'sticky_posts' ] = (bool)$new_instance[ 'sticky_posts' ]; $instance['show_thumbnails'] = isset( $new_instance['show_thumbnails'] ) ? (bool) $new_instance['show_thumbnails'] : false; $instance['show_date'] = isset( $new_instance['show_date'] ) ? (bool) $new_instance['show_date'] : false; return $instance; } /** Метод, который отображает виджет на веб-сайте. */ public function widget( $args, $instance ) { extract($args); $title = ( ! empty( $instance['title'] ) ) ? $instance['title'] : ''; $category = ( ! empty( $instance['category'] ) ) ? $instance['category'] : 0; $number_posts = ( ! empty( $instance['number_posts'] ) ) ? absint( $instance['number_posts'] ) : 5; $sticky_posts = ( isset( $instance['sticky_posts'] ) ) ? $instance['sticky_posts'] : false; $show_thumbnails = isset( $instance['show_thumbnails'] ) ? $instance['show_thumbnails'] : false; $show_date = isset( $instance['show_date'] ) ? $instance['show_date'] : false; // Последние посты $wordsmall_posts = new WP_Query( array( 'cat' => $category, 'posts_per_page' => $number_posts, 'ignore_sticky_posts' => $sticky_posts ) ); echo $before_widget; ?> <?php //Отображает заголовка виджета if ( ! empty( $instance['title'] ) ) { echo $args['before_title']; echo apply_filters( 'widget_title', empty( $instance['title'] ) ? '' : $instance['title'], $instance, $this->id_base ); echo $args['after_title']; } ?> <ul class="wscontainer-category-post"> <?php if( $wordsmall_posts -> have_posts() ) : ?> <?php while ( $wordsmall_posts -> have_posts() ) : $wordsmall_posts -> the_post(); ?> <li class="ws-items-cat-post"> <?php if ( $show_thumbnails && has_post_thumbnail() ) { ?> <div class="ws-cat-post-img"> <a href="<?php the_permalink(); ?>" rel="bookmark" title="<?php the_title_attribute(); ?>"><?php the_post_thumbnail(); ?></a> </div> <?php } ?> <div class="ws-cat-post-title"> <a href="<?php the_permalink(); ?>" rel="bookmark"><?php the_title(); ?></a> <?php if ( $show_date) { ?> <span class="ws-cat-post-date"><?php the_time('F j, Y'); ?></span> <?php } ?> </div> </li> <?php endwhile; ?> </ul> <?php wp_reset_postdata(); ?> <?php endif; ?> <?php echo $after_widget; } } // Регистрация виджета function ws_register_sidebar_posts() { register_widget( 'wordsmall_widget_post' ); } add_action( 'widgets_init', 'ws_register_sidebar_posts' );
Дальше вам нужно зайти в админку во вкладку «Внешний вид — Виджеты», найти наш виджет под названием «Последние записи WordSmall» и добавить его в область. Выбрать нужные параметры и сохранить.
Стили виджета
Последнее что осталось, так это добавить стили оформления в файл «style.css». И можно оценить нашу работу.
/* виджет постов */ ul.wscontainer-category-post li { position: relative; display: flex; gap: 1.5rem; margin-bottom: 1rem; padding-bottom: 1rem; align-items: center; } .ws-cat-post-img { overflow: hidden; -ms-flex-negative: 0; flex-shrink: 0; -ms-flex-preferred-size: 85px; flex-basis: 85px; line-height: 0; } .ws-cat-post-date { font-size: 14px; margin-top: 5px; color: #777; display: block; }