Закрепленные записи sticky post в категориях / тегах блога без плагина
Данная фишка Вордпресс “закрепляет” любой пост самым первым на главной странице независимо от его даты написания (напоминаю, в блоге записи выводятся по новизне). Это позволяет сразу показывать посетителям наиболее актуальный или важный контент. Если вы новичок, смотрите публикацию про создание и оформление sticky post, а дальше уже можете ознакомиться с сегодняшним хаком. Он автоматически фиксирует “липкие” посты сверху на страницах архивов категорий и тегов. В статье постараюсь максимально доходчиво объяснить всю логику метода.
Обновление 05.12.2019: Буквально недавно я рассматривал плагины sticky post в WordPress среди которых найдете альтернативное решение этой задачи и некоторые другие полезные модули по теме.
Включить данную опцию для поста можете как при его редактировании, так в общем разделе со списком всех публикаций. В первом случае это выглядит так (слева Gutenberg, справа старый редактор).
По умолчанию, данные посты закрепятся только на главной, но ведь было бы логично чтобы они также были на видном месте при переходе в тот или иной раздел. Мне кажется, я встречал такой механизм в нескольких шаблонах, и вот сейчас пришлось разбираться с его реализацией самостоятельно.
Исходный код нашел здесь выглядит он следующим образом (это полностью рабочий экземпляр, но тут есть нюансы, которые я слегка переделал… тем не менее, логику рассмотрим на этом примере):
function get_term_sticky_posts() { // Проверка находимся ли мы на странице архива категорий / category page... если нет - возвращает false if ( !is_category() ) return false; // Во-вторых, смотрим если вообще закрепленные посты, в противном случае - опять возвращаем false $stickies = get_option( 'sticky_posts' ); if ( !$stickies ) return false; // Ок, sticky-заметки имеются, и мы находимся в архиве рубрики, тогда считываем ID текущего category-объекта $current_object = get_queried_object_id(); // Создание запроса на получение прилепленных постов в разделе, получаем ID постов $args = [ 'nopaging' => true, 'post__in' => $stickies, 'cat' => $current_object, 'ignore_sticky_posts' => 1, 'fields' => 'ids' ]; $q = get_posts( $args ); return $q; } add_action( 'pre_get_posts', function ( $q ) { if ( !is_admin() // ВАЖНО, чтобы выполнялось только во фронт-энде && $q->is_main_query() // ВАЖНО, работаем только с main query && $q->is_category() // Срабатывает только для архивов категорий ) { // Проверка определена ли наша функция липких постов выше дабы не было ошибок if ( function_exists( 'get_term_sticky_posts' ) ) { // Смотрим есть ли вообще закрепленные записи $stickies = get_term_sticky_posts(); if ( $stickies ) { // Далее удаляем найденные прилипленные публикации дабы в итоговом результате не было дублей $q->set( 'post__not_in', $stickies ); // Выводим sticky-посты только на первой странице архива, если надо на всех, аккуратно убираете данное условие if ( !$q->is_paged() ) { // Добавляем липкие заметки перед остальными с помощью фильтра the_posts add_filter( 'the_posts', function ( $posts ) use ( $stickies ) { $term_stickies = get_posts( ['post__in' => $stickies, 'nopaging' => true] ); $posts = array_merge( $term_stickies, $posts ); return $posts; }, 10, 1 ); } } } } }); |
Итак, тут имеются 2 блока:
- Новая функция get_term_sticky_posts, что считывает все прикрепленные посты из текущей активной категории. Пошаговый алгоритм вы можете прочитать в комментариях кода, которые я перевел с английского. Здесь также не обошлось без функции get_queried_object, рассмотренной в прошлом посте.
- Дальше с помощью хука “вклиниваетесь” в событие pre_get_posts до выполнения WP_Query и запроса в БД, дабы, во-первых, считать список прикрепленных постов и, во-вторых, разместить его перед всеми остальными записями. Опять же смотрите комменты в примере выше.
Несколько дополнений от автора:
- Данный сниппет добавляете в файл functions.php и все, никаких дополнительных правок шаблонов категорий/архивов не нужно. Это плюс!
- Код выше работает только для категорий (category), но может быть легко модифицирован и под другие таксономии. Еще один плюс.
- Для работы надо как минимум PHP 5.4+!
НО есть одна неприятная ошибка!
В том же треде на stackexchange имеется замечание, что хак не справляется с ситуацией, когда в URL-адресе пользователь допустит ошибку в названии раздела, например – site.com/categggory/ — вместо того чтобы выдать страницу 404 ошибки система посчитает это названием реальной таксономии, т.к. значение будет сохранено в переменную $q.
К сожалению, предложенный вариант с использованием is_tax у меня не прокатил, возможно, потому что данная функции срабатывает для новых пользовательских таксономий и игнорирует теги/разделы. Вместо этого я пробовал использовать term_exists() – вроде как, сработало.
Мой вариант
Эта версия сниппета закрепляет записи sticky post не только в рубриках, но и для тегов. Кроме того, ошибка с неправильным вводом таксономии все же ведет на 404 ошибку, как и должно быть.
function get_term_sticky_posts() { if (( !is_category() ) && ( !is_tag() )) return false; $stickies = get_option( 'sticky_posts' ); if ( !$stickies ) return false; $current_object = get_queried_object_id(); if ( is_category() ) { $args = [ 'nopaging' => true, 'post__in' => $stickies, 'cat' => $current_object, 'ignore_sticky_posts' => 1, 'fields' => 'ids' ]; } elseif ( is_tag() ) { $args = [ 'nopaging' => true, 'post__in' => $stickies, 'tag_id' => $current_object, 'ignore_sticky_posts' => 1, 'fields' => 'ids' ]; } $q = get_posts( $args ); return $q; } add_action( 'pre_get_posts', function ( $q ) { if ( !is_admin() && $q->is_main_query() && ( ($q->is_category()) || ($q->is_tag()) ) && ( (term_exists(get_query_var('category_name'))) || (term_exists(get_query_var('tag'))) ) ) { if ( function_exists( 'get_term_sticky_posts' ) ) { $stickies = get_term_sticky_posts(); if ( $stickies ) { $q->set( 'post__not_in', $stickies ); if ( !$q->is_paged() ) { add_filter( 'the_posts', function ( $posts ) use ( $stickies ) { $term_stickies = get_posts( ['post__in' => $stickies, 'nopaging' => true] ); $posts = array_merge( $term_stickies, $posts ); return $posts; }, 10, 1 ); } } } } }); |
По коддингу тут лишь несколько логических изменений:
- Во-первых, для хука pre_get_posts я добавил обработку тегов и проверку на существование названия введенной таксономии (term_exists).
- Во-вторых, в функцию get_term_sticky_posts вставил обработку меток (проверки + считывание соответствующих закрепленных постов).
Решение я тестил на последних версиях WordPress 5.2.x, при этом версия PHP 5.6+. Пока полет нормальный. Из альтернатив можно глянуть модуль Category Sticky Post, но он несколько лет не обновлялся. Если есть что дополнить, пишите.
Блог Wordpress Inside поможет вам научиться работать в вордпресс, закрепить и расширить имеющиеся знания. Плагины и шаблоны, разные хаки и функции wp, оптимизация и безопасность системы – все это и намного больше вы сможете найти на страницах нашего проекта!
Если хотите быстро и оперативно получать последние новости и статьи, то рекомендуем подписаться на обновления блога:
- Як сховати відсутні товари в Woocommerce шорткодах та схожих товарах
- Сервіс AdMaven + плагін для монетизації трафіка на WordPress сайтах
- Плагіни для створення стрічки новин з біжучим рядком в WordPress
- Як змінити розміщення кнопки оформлення замовлення в WooCommerce
- Плагін WHWS Display In Stock Products First – відображення товарів в наявності першими
- Підписка MonsterONE: чи варто використовувати цей сервіс у 2023 році? (+5 продуктів, які треба скачати в першу чергу)
- Онлайн генератор ссылок на мессенджеры для WordPress и не только
- WooCommerce (46)
- Безопасность (12)
- Видео (6)
- Виджеты (28)
- Возможности (141)
- Вопрос-ответ (6)
- Начинающим (52)
- Новости (46)
- Оптимизация (23)
- Плагины (246)
- Сервисы (87)
- Хаки и секреты (87)
- Шаблоны (45)
- Оптимизируем WordPress header и удаляем лишний код (5,19 из 7, голосов - 43)
- Как создать пункт меню без ссылки в wordpress (6,39 из 7, голосов - 23)
- Добавление кнопки Вконтакте, Facebook и Twitter в wordpress блог (6,14 из 7, голосов - 21)
- Выполнение jQuery скриптов при выборе вариаций товаров в WooCommerce (3,96 из 7, голосов - 26)
- Хаки для вариаций товаров в WooCommerce (5,29 из 7, голосов - 17)
- Вывод текста в блоге только на главной (6,85 из 7, голосов - 13)
- Как убрать category в WordPress категориях — зачем это делать, плагины для реализации (5,31 из 7, голосов - 16)
- Дизайн Мания - о веб-дизайне и не только.
- Tod's Blog - все про заработок онлайн.
- Вебдванольные заметки - обзоры веб-сервисов.
- Зачем нужны Wi-Fi ретрансляторы и как выбрать подходящую модель
- Введение в онлайн-казино Slotor777: многообразие игр и привлекательные бонусы
- Необходимость использования облачного хранилища в наше время, что важно и как выгодно?
- Спрощення процесу звітності за допомогою програми BAS Бухгалтерія
- Технологія підключення інтернету GPON та її переваги
- За що гравці найбільше цінують Lineage 2
- Для каких проектов нужна аренда виртуального сервера и что такое VPS
- Особливості MMORPG ігор (зокрема Lineage 2) та чому люди в них грають