Создание своего виджета для WordPress

В этой статье мы поговорим о том, как создать свой собственный виджет для вашего сайта на 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. Новый виджет будет выводить свежие посты из любой категории или всех сразу. Вы сможете настроить его параметры, такие как показ миниатюры, даты и возможность скрыть прилепленные записи.

  1. Создайте файл-php и поместите в него ниже представленный код
  2. Сохраните файл под названием «ws-post-widget.php»
  3. Загрузите его на сайт в вашу тему оформления, конечно в дочернюю.
  4. Откройте файл 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;
}
Оставить ответ

Ваш адрес email не будет опубликован. Обязательные поля помечены *