Гид по технологиям

Виджет WordPress: случайная запись с миниатюрой

6 min read WordPress Обновлено 16 Dec 2025
Виджет WordPress: случайная запись с миниатюрой
Виджет WordPress: случайная запись с миниатюрой

Миниатюра случайной записи на сайдбаре

Многие ищут готовый плагин, который делает ровно то, что нужно. Но если у вас есть базовые навыки PHP и понимание структуры WordPress, часто проще написать собственный виджет. В этой статье шаг за шагом создадим виджет, который выбирает одну случайную запись, берёт её featured image (миниатюру) и выводит в сайдбар как визуальную рекомендацию для посетителей.

Это продолжение серии по кастомизации тем WordPress. Если вы только начинаете — коротко: виджет — это PHP‑класс, который регистрируется через API виджетов WordPress. Внутри класса вы создаёте форму настроек, обработчик обновления и функцию вывода (widget), где и размещается ваш запрос к базе и цикл (The Loop).

Что мы делаем и зачем

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

Кому пригодится: блогерам, владельцам медиа и всем, кто хочет увеличить внутреннюю навигацию на сайте.

Ключевые концепции: запросы WordPress и цикл

Определения в одну строку:

  • Запрос (query): параметры, которыми WordPress выбирает набор записей из базы. Пример: «последние 10 записей».
  • Цикл (The Loop): стандартный способ пройти по результатам запроса и вывести содержимое каждой записи.

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

Важно: есть несколько способов сделать запрос. query_posts() изменяет глобальный главный запрос и обычно не рекомендуется. Гораздо безопаснее использовать WP_Query или get_posts(), чтобы не ломать основной вывод страницы.

Базовый код виджета

Создайте файл в каталоге вашего сайта wp-content/plugins, например random-post-widget.php. Писать можно прямо на сервере или локально, а затем загрузить файл.

Ниже — минимальный рабочий шаблон плагина и класса виджета. Это «скелет», в который мы добавим функциональность.

 'RandomPostWidget', 'description' => 'Displays a random post with thumbnail');
        parent::__construct('random_post_widget', 'Random Post and Thumbnail', $widget_ops);
    }

    public function form($instance)
    {
        $instance = wp_parse_args((array) $instance, array('title' => ''));
        $title = $instance['title'];
        ?>
        

Это мой новый виджет!

"; echo $args['after_widget']; } } add_action('widgets_init', function(){ register_widget('RandomPostWidget'); });

Этот код создаёт виджет с настройкой для названия. На данный момент функция widget() просто выводит статическое сообщение — дальше мы заменим это на запрос и вывод миниатюры.

Элемент интерфейса виджета в WordPress

Простейший запрос и цикл

Чтобы получить список записей, можно использовать query_posts(), но лучше использовать WP_Query. Сначала покажу самый простой пример с query_posts() для понимания, затем — рекомендуемый вариант.

Замените место “// WIDGET CODE GOES HERE” на этот минимальный код (пример для понимания):

// НЕ рекомендуется в продакшене: изменяет глобальный цикл
query_posts('');
if (have_posts()) :
    while (have_posts()) : the_post();
        the_title();
    endwhile;
endif;
wp_reset_query();

Этот пример просто выводит заголовки по умолчанию (обычно 10 последних записей). Лучше оформить вывод HTML и ссылки:

query_posts('');
if (have_posts()) :
    echo '';
endif;
wp_reset_query();

Но мы хотим одну запись и случайную сортировку. Параметры можно задать прямо в строке запроса:

query_posts('posts_per_page=1&orderby=rand');

Обновите вывод, чтобы показать миниатюру. Пример с query_posts():

query_posts('posts_per_page=1&orderby=rand');
if (have_posts()) :
    echo '
'; while (have_posts()) : the_post(); echo ''; echo get_the_post_thumbnail(get_the_ID(), array(220,200)); echo '' . get_the_title() . ''; echo ''; endwhile; echo '
'; endif; wp_reset_query();

Этот код работает, но есть важные замечания по производительности и безопасности ниже.

Пример вывода миниатюры в сайдбаре

Рекомендуемый вариант: WP_Query и безопасный вывод

Используйте WP_Query, чтобы не изменять глобальный запрос. Также экранируйте вывод и используйте кеширование, чтобы снизить нагрузку.

Пример кода внутри метода widget():

// Рекомендуемый вариант с WP_Query
$cache_key = 'rpw_random_post_' . get_current_blog_id();
$cached = get_transient($cache_key);
if ($cached !== false) {
    echo $cached;
} else {
    $args = array(
        'posts_per_page' => 1,
        'orderby' => 'rand',
        'post_status' => 'publish',
    );
    $q = new WP_Query($args);

    ob_start();
    if ($q->have_posts()) {
        echo '
'; while ($q->have_posts()) { $q->the_post(); $permalink = esc_url(get_the_permalink()); $title = esc_html(get_the_title()); $thumbnail = get_the_post_thumbnail(get_the_ID(), array(220,200)); echo ''; echo $thumbnail; echo '' . $title . ''; echo ''; } echo '
'; } wp_reset_postdata(); $output = ob_get_clean(); // Кешируем результат на короткий срок, например 10 минут set_transient($cache_key, $output, 10 * MINUTE_IN_SECONDS); echo $output; }

Пояснения:

  • WP_Query безопасно изолирует запрос от основного цикла.
  • esc_url() и esc_html() защищают вывод от XSS.
  • get_the_post_thumbnail() возвращает корректный HTML для изображения.
  • transient API используется для кеширования, чтобы не запускать случайный запрос на каждой загрузке страницы.

Варианты и улучшения

  1. Альтернатива: get_posts()
  • Если вам нужен простой массив записей без сложных настроек, используйте get_posts($args). Он удобен для одноразовых выборок.
  1. Ограничение по рубрике или метке
  • Добавьте параметры ‘cat’ или ‘tax_query’ в $args, чтобы показывать записи только из нужной категории.
  1. Несколько записей
  • Установите posts_per_page > 1 и адаптируйте HTML в виджете для списка миниатюр.
  1. Замена порядка сортировки
  • Вместо rand можно выбрать orderby => ‘date’ или мощные соритровки по метаданным.
  1. Ленивая загрузка изображений
  • Для производительности добавьте loading=”lazy” к тэгу img (можно фильтровать через post_thumbnail_html).

Безопасность и производительность

Важно:

Никогда не выводите данные без экранирования. Для URL — esc_url(), для текста — esc_html(), для атрибутов — esc_attr().

Рекомендации:

  • Используйте WP_Query или get_posts() вместо query_posts().
  • Кешируйте результат с помощью transients или внешнего кеша (Redis, Memcached).
  • Ограничьте частоту обновления кеша — например, 5–30 минут в зависимости от частоты обновления контента.
  • Если на сайте много трафика, разгрузите виджет через fragment caching или статический HTML.

Совместимость и версии WordPress

Работает с большинством версий WordPress текущих лет. Если у вас очень старая тема, убедитесь, что:

  • Функция get_the_post_thumbnail поддерживается (включена с WP 3.0+).
  • Ваша тема использует поддержку миниатюр (add_theme_support(‘post-thumbnails’)).

Если виджет не отображается, проверьте логи PHP и активность плагина.

Отладка и распространённые проблемы

Проверьте по шагам:

  • Плагин активирован в админке «Плагины».
  • Виджет добавлен в сайдбар через Внешний вид → Виджеты.
  • У записей есть миниатюры и статус publish.
  • Нет фатальных ошибок PHP — включите WP_DEBUG в локальной среде.
  • Кеш не содержит устаревший HTML — попробуйте удалить transient с помощью delete_transient().

Типичные симптомы и решения:

  • Пустой вывод: убедитесь, что в базе есть опубликованные записи с миниатюрами.
  • Неправильное изображение: проверьте размеры и наличие image sizes в теме.
  • Повторяющаяся одна и та же запись часто: уменьшите время кеша или отключите кеширование при тестировании.

Критерии приёмки

  • Виджет успешно регистрируется и доступен в панели Виджеты.
  • При добавлении в сайдбар выводится одна случайная опубликованная запись.
  • Изображение и заголовок кликабельны и ведут на страницу записи.
  • Все внешние данные экранированы (esc_url, esc_html).
  • Кеширование работает и снижает количество запросов к БД.

Контрольный список по ролям

Для разработчика:

  • Написать и зарегистрировать класс виджета.
  • Реализовать безопасный WP_Query и вывод.
  • Добавить кеширование и сброс транзиентов.

Для контент‑менеджера:

  • Убедиться, что у записей есть миниатюры.
  • Добавить подходящую категорию/теги при необходимости.

Для администратора сайта:

  • Активировать плагин и добавить виджет в сайдбар.
  • Проверить нагрузку на БД после активации.

Короткое руководство по развертыванию

  1. Создайте файл random-post-widget.php в wp-content/plugins.
  2. Вставьте код плагина (см. раздел выше).
  3. Активируйте плагин в админ‑панели WordPress → Плагины.
  4. Перейдите в Внешний вид → Виджеты и перетащите Random Post and Thumbnail в сайдбар.
  5. При необходимости настройте заголовок виджета и время кеша.

Критические примеры, когда подход не подходит

  • Сайт с тысячами записей и частыми обновлениями: частые рандомные запросы без кеша создадут нагрузку на БД.
  • Сайты с высокими требованиями к SEO: случайный показ популярных материалов может мешать контролю над внутренней перелинковкой.
  • Если темы или плагины вмешиваются в глобальный цикл через query_posts(), используйте изолированный WP_Query.

Короткий глоссарий

  • WP_Query — класс для выполнения запросов к записям WordPress.
  • The Loop — стандартный цикл для вывода найденных записей.
  • transient — временный кеш в базе данных WordPress.

Вывод

Создать собственный виджет для WordPress просто. Начните с простого кода, затем улучшайте: замените query_posts() на WP_Query, экранируйте вывод, добавьте кеширование и опции для администратора. Такой подход даёт гибкость и контроль над тем, как пользователи видят дополнительные материалы на вашем сайте.

Кратко:

  • Используйте WP_Query для безопасных выборок.
  • Экранируйте все внешние данные.
  • Кешируйте вывод, если сайт получает значительный трафик.

Финальный пример виджета в действии

Заметки:

  • Если вы хотите расширить функциональность (несколько миниатюр, фильтрация по категории, опции в админке), добавьте поля в метод form() и сохраняйте их в update().
Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Не видно файлов в WSL — быстрое решение
Windows

Не видно файлов в WSL — быстрое решение

Ошибка RdrCEF.exe в Adobe Reader — как исправить
Windows

Ошибка RdrCEF.exe в Adobe Reader — как исправить

Дополнения Firefox для GIF: задержка, пауза, создание
Браузер расширения

Дополнения Firefox для GIF: задержка, пауза, создание

Автономные файлы в Windows 11: включение и отключение
Windows

Автономные файлы в Windows 11: включение и отключение

Ошибка Hulu P-DEV323 — как исправить
Стриминг

Ошибка Hulu P-DEV323 — как исправить

Несколько аккаунтов Dropbox на Mac
Инструкции

Несколько аккаунтов Dropbox на Mac