Intereting Posts
Сообщения для сообщений Ordering 'connected_items' Отображать только дочерние страницы определенной страницы в результатах поиска Использование одинаковой базы данных пользователей на субдомене Показывать значение get_sub_field, если оно существует Форма контакта 7 – как манипулировать данными до отправки почты? Список всех элементов в алфавитном порядке / порядок сортировки Выполнение запросов в tag.php удалить меню администратора wp по роли пользователя пользователя WP Налоговый запрос и порядок по налоговым запросам не работают Не удается загрузить изображение продукта в панели инструментов поставщика pro с помощью браузера Chrome Перевести названия виджетов с помощью плагина qTranslate Проверьте, есть ли тег, категория или автор в файле archive.php Отключить сортировку элементов управления в разделах Стилей очереди после плагина Как удалить вкладки справки?

WP_Query: Почему липкий пост не первый элемент в цикле?

У меня есть настраиваемый цикл WP_Query основанный на переменных meta_value:

 $meta_cat = get_sub_field('category'); $posts = new WP_Query( array( 'cat' => $meta_cat, 'posts_per_page' => get_sub_field('recent_ppp'), ) ); 

Но почему-то, когда я сделаю сообщение липким, он не будет показан как первый элемент в цикле while.

Я знаю, что ignore_sticky_posts по умолчанию установлен в false, поэтому я не буду его менять. Также попробовал посмотреть в документации order_by, если какое-то значение связано с липким сообщением, но это не так.

Хотя order_by => 'post__in' может быть близок:

Сохраните заказ после ID, указанный в массиве post__in

Но когда я устанавливаю post__in => get_options('sticky_posts') только липкий пост.

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

Если вы посмотрите на исходный код, где включены WP_Query , мы обнаруживаем следующее условие перед WP_Query как WP_Query продолжает включать липкие сообщения

 if ( $this->is_home && $page <= 1 && is_array($sticky_posts) && !empty($sticky_posts) && !$q['ignore_sticky_posts'] ) { 

Большой игровой игрок – это условие is_home . Условные условия внутри WP_Query устанавливаются в соответствии с переданными ему аргументами, а не на странице, где выполняется запрос. Поскольку вы передаете cat в качестве аргумента, значение is_home будет установлено в false, а is_category будет установлено значение true. Поскольку is_home имеет значение false, указанное выше условие не выполняется, и листы не включены.

ВОЗМОЖНАЯ РАБОТА-ВОКРУГ – Непроверенная

Что мы можем сделать, это вручную установить is_home в true через pre_get_posts . Все, что нам нужно сделать, это передать 'wpse_is_home' => true, в ваш пользовательский экземпляр WP_Query

Затем мы запускаем действие pre_get_posts следующим образом.

 add_action( 'pre_get_posts', function ( $q ) { if ( true === $q->get( 'wpse_is_home' ) ) $q->is_home = true; }); 

РЕДАКТИРОВАТЬ

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

Мы можем попробовать следующее, все еще pre_get_posts внутри нашего действия pre_get_posts

 add_action( 'pre_get_posts', function ( $q ) { remove_action( current_action(), __FUNCTION__ ); if ( true !== $q->get( 'wpse_is_home' ) ) return; // Make sure get_sub_field exists, if not, bail if ( !function_exists( 'get_sub_field' ) ) return; // Lets query everything to keep code clean $meta_cat = get_sub_field( 'category' ); // Copied from your code $meta_cat = filter_var( $meta_cat, FILTER_VALIDATE_INT ); // Make sure we have a value, if not, bail if ( !$meta_cat ) return; $q->set( 'cat', $meta_cat ); // Set pagination if recent_ppp exists $ppp = get_sub_field( 'recent_ppp'); $ppp = filter_var( $ppp, FILTER_VALIDATE_INT ); if ( $ppp ) $q->set( 'posts_per_page', $ppp ); // Set is_home to true $q->is_home = true; // Get all stickies $stickies = get_option( 'sticky_posts' ); // Make sure we have stickies, if not, bail if ( !$stickies ) return; // Query the stickies according to category $args = [ 'post__in' => $stickies, 'posts_per_page' => -1, 'ignore_sticky_posts' => 1, // Ignore stickies 'cat' => $meta_cat, 'orderby' => 'post__in', 'order' => 'ASC', 'fields' => 'ids' // Get only post ID's ]; $valid_sticky_ids = get_posts( $args ); // Make sure we have valid ids if ( !$valid_sticky_ids ) { $q->set( 'post__not_in', $stickies ); return; } // Remove these ids from the sticky posts array $invalid_ids = array_diff( $stickies, $valid_sticky_ids ); // Check if we still have ids left in $invalid_ids if ( !$invalid_ids ) return; // Lets remove these invalid ids from our query $q->set( 'post__not_in', $invalid_ids ); }); 

Прежде чем запускать наш пользовательский запрос, нам нужно убедиться, что get_sub_field существует, и что самое главное, что get_sub_field( 'category' ) задан и действителен. Это позволит избежать катастрофического сбоя, который приведет к возврату всех сообщений, независимо от того.

Ваш WP_Query может выглядеть примерно так, поскольку нам нужно передать 'wpse_is_home' => true :

 if ( function_exists( 'get_sub_field' ) && filter_var( get_sub_field( 'category' ), FILTER_VALIDATE_INT ) ) { $args = [ 'wpse_is_home' => true ]; $posts_array = new WP_Query( $args ); // DO NOT USE $posts // Run your loop as normal } 

ПОСЛЕДНИЕ ИЗМЕНЕНИЯ

Код проверен и работает как ожидалось