Intereting Posts
Переименовал мой сайт (URL) – как мне переименовать все ссылки внутри страницы на старый URL? Лучший способ перенаправить сайт в подкаталог root? Сохранить метабокс с несколькими клетками checkbox «Создать новую дочернюю запись» из родительского сообщения с помощью кнопки – не используя раскрывающийся список атрибутов В том числе post_type = 'wiki' в авторских архивах Почему все мои URL-адреса http обращаются к https? Woocommerce показывает изображения размытыми на странице описания Как создать редактор кода для моего плагина.? Показать другой код на главной странице на другие страницы Отображение терминов по первой букве Включить несколько идентификаторов страниц в цикле Проблемы с очисткой кеша взорвать массив в пределах короткого кода добавление выбора цвета в настройке (разработка темы) WP-Admin не работает должным образом в WordPress multisite с подкаталогами

Показывать только сообщения, которые можно прокомментировать или иметь настраиваемое мета-поле

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

Теперь я хотел бы добавить возможность исключений – показать определенные сообщения, для которых комментарии закрыты, тем не менее. Они отмечены специальным полем «show_always».

Я пытался:

function wpjj_filter_sticky( $query ) { $meta_query = array( 'relation' => 'OR', array( 'key' => 'show_aways', 'value' => 'yes', 'compare' => 'EXISTS' ), array ( 'comment_status' => 'open' ) ); $query->set( 'meta_query', $meta_query ); } add_filter( 'pre_get_posts', 'wpjj_filter_sticky' ); 

Но он будет показывать только сообщения с мета, а не открытые сообщения.

Давайте попробуем следующее:

По умолчанию все сообщения возвращаются независимо от comment_status , поэтому позволяет запускать основной запрос как обычно, то есть запрашивать все сообщения независимо от comment_status .

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

  • comment_status закрытого

  • которые имеют мета значение не yes

post__not_in идентификаторы будут переданы как post__not_in в основной запрос, чтобы исключить эти сообщения

Я думаю, что это лучший подход, потому что обработка SQL, которая включает в себя мета-запросы, может стать очень запутанной, особенно когда вы начинаете добавлять сложные вложенные мета-запросы. Пусть WP_Query обрабатывает часть meta_query для нас.

Мы по-прежнему будем использовать параметр comment_status который поддерживается настраиваемым фильтром @TheDeadMedic в связанном вами вопросе

 add_action( 'pre_get_posts', function ( $q ) { if ( $q->is_home() && $q->is_main_query() ) { // Run our secondary query to get the posts to exclude $args = [ 'posts_per_page' => -1, 'comment_status' => 'closed', 'meta_query' => [ 'relation' => 'OR', [ // Compensate for posts which have the custom field set but not set to yes 'key' => 'show_always', 'value' => 'yes', 'compare' => 'NOT IN' // Get posts which value is not yes ], [ // Compensate for posts which does not have the custom fields 'key' => 'show_always', 'compare' => 'NOT EXISTS' // Get posts which value is not yes ] ], 'fields' => 'ids', // Return only post ID's 'suppress_filters' => false, // Allow the comment_status filter // Any other parameters ]; $exclude_ids = get_posts( $args ); // Now we can exclude the ID's we just queried $q->set( 'post__not_in', $exclude_ids ); } }); 

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

Вышеприведенный код теперь протестирован и работает как ожидалось

ИЗМЕНИТЬ из комментариев

@birgire отправил новый билет на трафик (траковый билет № 35601 ), чтобы узнать, почему comment_status недоступен в WP_Query по умолчанию. Мы надеемся, что в ближайшем будущем мы увидим, что это включено в ядро. Как только это произойдет, пользовательский фильтр больше не понадобится