Как создать виджет из кратких записей WordPress

Создание собственного виджета WordPress — отличное решение, если стандартные виджеты не удовлетворяют вашим требованиям. В этом руководстве мы подробно рассмотрим, как создать виджет, который выводит краткие записи (excerpt) из ваших публикаций. Такой виджет поможет улучшить пользовательский опыт, показывая пользователям анонсы статей прямо в сайдбаре или другом виджетизированном месте.

Что такое виджет и зачем создавать свой

Виджеты — это небольшие блоки, которые можно размещать в сайдбаре, футере и других областях сайта. WordPress предоставляет множество стандартных виджетов, но часто их функционал ограничен и не всегда подходит под конкретные задачи проекта.

Создавая собственный виджет, вы получаете полный контроль над его функционалом: выводом данных, дизайном и настройками. Это особенно важно, когда нужно показывать специфическую информацию, например, краткие записи с определёнными параметрами.

Виджет, который мы создадим, позволит:

  • Выводить выбранное количество кратких записей;
  • Фильтровать записи по категориям;
  • Настраивать заголовок виджета;
  • Управлять длиной вывода excerpt;
  • Использовать кастомный HTML для оформления.

Создание базового виджета WordPress

Для начала создадим простой класс виджета, который наследуется от WP_Widget. Это стандартный способ создания виджетов в WordPress.

Добавим код в файл functions.php вашей темы или в отдельный плагин:

class Wpcatalog_Widget_Excerpt extends WP_Widget {
    public function __construct() {
        parent::__construct(
            'wpcatalog_excerpt',
            'WPCatalog: Краткие записи',
            array('description' => 'Выводит краткие записи с настройками')
        );
    }

    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'];
        }

        $number = !empty($instance['number']) ? absint($instance['number']) : 5;
        $category = !empty($instance['category']) ? $instance['category'] : '';
        $excerpt_length = !empty($instance['excerpt_length']) ? absint($instance['excerpt_length']) : 20;

        $query_args = array(
            'posts_per_page' => $number,
            'post_status' => 'publish',
        );

        if ($category) {
            $query_args['category_name'] = $category;
        }

        $the_query = new WP_Query($query_args);

        if ($the_query->have_posts()) {
            echo '<ul class="wpcatalog-excerpt-list">';
            while ($the_query->have_posts()) {
                $the_query->the_post();
                $excerpt = wp_trim_words(get_the_excerpt(), $excerpt_length, '...');
                echo '<li><a href="' . get_permalink() . '">' . get_the_title() . '</a><br><small>' . $excerpt . '</small></li>';
            }
            echo '</ul>';
            wp_reset_postdata();
        } else {
            echo '<p>Нет записей для отображения.</p>';
        }

        echo $args['after_widget'];
    }

    public function form($instance) {
        $title = !empty($instance['title']) ? $instance['title'] : 'Краткие записи';
        $number = !empty($instance['number']) ? absint($instance['number']) : 5;
        $category = !empty($instance['category']) ? $instance['category'] : '';
        $excerpt_length = !empty($instance['excerpt_length']) ? absint($instance['excerpt_length']) : 20;
        ?>
        <p>
            <label for="<?php echo esc_attr($this->get_field_id('title')); ?>">Заголовок:</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('number')); ?>">Количество записей:</label>
            <input class="tiny-text" id="<?php echo esc_attr($this->get_field_id('number')); ?>" name="<?php echo esc_attr($this->get_field_name('number')); ?>" type="number" step="1" min="1" value="<?php echo esc_attr($number); ?>" size="3">
        </p>
        <p>
            <label for="<?php echo esc_attr($this->get_field_id('category')); ?>">Категория (slug):</label>
            <input class="widefat" id="<?php echo esc_attr($this->get_field_id('category')); ?>" name="<?php echo esc_attr($this->get_field_name('category')); ?>" type="text" value="<?php echo esc_attr($category); ?>">
            <small>Оставьте пустым для всех категорий</small>
        </p>
        <p>
            <label for="<?php echo esc_attr($this->get_field_id('excerpt_length')); ?>">Длина анонса (слов):</label>
            <input class="tiny-text" id="<?php echo esc_attr($this->get_field_id('excerpt_length')); ?>" name="<?php echo esc_attr($this->get_field_name('excerpt_length')); ?>" type="number" step="1" min="5" value="<?php echo esc_attr($excerpt_length); ?>" size="3">
        </p>
        <?php
    }

    public function update($new_instance, $old_instance) {
        $instance = array();
        $instance['title'] = !empty($new_instance['title']) ? sanitize_text_field($new_instance['title']) : '';
        $instance['number'] = !empty($new_instance['number']) ? absint($new_instance['number']) : 5;
        $instance['category'] = !empty($new_instance['category']) ? sanitize_text_field($new_instance['category']) : '';
        $instance['excerpt_length'] = !empty($new_instance['excerpt_length']) ? absint($new_instance['excerpt_length']) : 20;
        return $instance;
    }
}

function wpcatalog_register_widget() {
    register_widget('Wpcatalog_Widget_Excerpt');
}
add_action('widgets_init', 'wpcatalog_register_widget');

Настройка и использование виджета

После добавления кода и активации виджета в разделе «Внешний вид» → «Виджеты» появится новый виджет «WPCatalog: Краткие записи».

В настройках виджета вы сможете указать:

  • Заголовок виджета, который будет отображаться на сайте.
  • Количество выводимых записей – например, 3 или 5.
  • Slug категории, если хотите ограничить записи определённой категорией.
  • Длину вывода анонса в количестве слов, чтобы текст не был слишком длинным.

Это позволит гибко настраивать отображение коротких записей без использования дополнительных плагинов.

Расширение функционала: добавляем миниатюры в виджет

Для улучшения визуальной привлекательности виджета можно добавить вывод миниатюр записей. Для этого отредактируем метод 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'];
    }

    $number = !empty($instance['number']) ? absint($instance['number']) : 5;
    $category = !empty($instance['category']) ? $instance['category'] : '';
    $excerpt_length = !empty($instance['excerpt_length']) ? absint($instance['excerpt_length']) : 20;

    $query_args = array(
        'posts_per_page' => $number,
        'post_status' => 'publish',
    );

    if ($category) {
        $query_args['category_name'] = $category;
    }

    $the_query = new WP_Query($query_args);

    if ($the_query->have_posts()) {
        echo '<ul class="wpcatalog-excerpt-list">';
        while ($the_query->have_posts()) {
            $the_query->the_post();
            $excerpt = wp_trim_words(get_the_excerpt(), $excerpt_length, '...');
            $thumbnail = get_the_post_thumbnail(get_the_ID(), 'thumbnail');
            echo '<li class="wpcatalog-excerpt-item">';
            if ($thumbnail) {
                echo '<div class="wpcatalog-excerpt-thumb">' . $thumbnail . '</div>';
            }
            echo '<div class="wpcatalog-excerpt-content">';
            echo '<a href="' . get_permalink() . '">' . get_the_title() . '</a><br>';
            echo '<small>' . $excerpt . '</small>';
            echo '</div></li>';
        }
        echo '</ul>';
        wp_reset_postdata();
    } else {
        echo '<p>Нет записей для отображения.</p>';
    }

    echo $args['after_widget'];
}

Не забудьте добавить CSS стили, чтобы миниатюры и текст выглядели аккуратно:

.wpcatalog-excerpt-list { list-style: none; padding: 0; margin: 0; }
.wpcatalog-excerpt-item { display: flex; margin-bottom: 10px; }
.wpcatalog-excerpt-thumb { margin-right: 10px; }
.wpcatalog-excerpt-content a { font-weight: bold; text-decoration: none; }
.wpcatalog-excerpt-content small { color: #777; }

Использование готовых плагинов для показа кратких записей

Если вы не хотите писать код, можно воспользоваться плагинами, которые позволяют выводить краткие записи в виджетах:

  • Recent Posts Widget Extended — мощный плагин с множеством настроек для вывода последних записей с миниатюрами, датами, категориями и excerpt.
  • Custom Recent Posts Widget — простой и легкий виджет с возможностью настроить количество символов в анонсе и фильтрацию по категориям.
  • WP Show Posts — универсальный плагин для вывода списков записей с большим количеством параметров.

Эти плагины удобны для быстрого старта, но собственный виджет даёт большую гибкость и возможность кастомизации.

Заключение

Создание собственного виджета для показа кратких записей — отличная практика для разработчиков WordPress. Вы можете точно настроить вывод, добавить уникальный дизайн и функции, которые нужны именно вашему сайту. В статье мы рассмотрели базовый пример с настройками и расширили его выводом миниатюр. Также привели альтернативные готовые решения в виде плагинов.

Если хотите, можете развить данный виджет, добавив, например, вывод пользовательских таксономий, сортировку по популярности или дату публикации в более удобном формате. Главное — понимание структуры виджетов и WP_Query.

Как удалить или изменить meta robots в WordPress для улучшения SEO
26.01.2026
Как создать собственный REST API в WordPress
01.12.2025
Как создать динамические шорткоды в WordPress: практическое руководство
15.11.2025
Как использовать метод AJAX в WooCommerce для обновления корзины без перезагрузки
05.05.2026
Как использовать REST API в WordPress для каталогов товаров
12.01.2026