Как выбрать записи из одной категории, но исключить записи из другой категории?
Я пытаюсь выбрать записи, которые относятся к категории с ID 4
, но исключить записи, которые также относятся к категории с ID 2
.
Вот что я пробую:
$query = new WP_Query(array(
"cat__in" => array(4), // Включить категорию 4
"cat__not_in" => array(2), // Исключить категорию 2
"post_type" => "post", // Тип записи - посты
"post_status" => "publish", // Только опубликованные
"orderby" => "date", // Сортировка по дате
"order" => "DESC", // По убыванию
"posts_per_page" => $limit, // Лимит записей
"offset" => 0 // Смещение
));
Однако выборка работает неправильно. Что я делаю не так?
Оказывается, это можно сделать 4 разными способами
Использование cat
с отрицательным числом
$query = new WP_Query(array(
"cat" => "4, -2",
// ...
));
Использование category__in
и category__not_in
Я ошибочно использовал cat__in
и cat__not_in
, которые не являются допустимыми параметрами WP_Query
$query = new WP_Query(array(
"category__in" => array(4),
"category__not_in" => array(2),
// ...
));
Использование tax_query
$query = new WP_Query(array(
"tax_query" => array(
"relation" => "AND",
array(
"taxonomy" => "category",
"field" => "term_id",
"terms" => array(4)
),
array(
"taxonomy" => "category",
"field" => "term_id",
"terms" => array(2),
"operator" => "NOT IN"
),
),
// ...
));
Использование фильтра pre_get_posts
(как предложил Brad Dalton)
function exclude_posts_from_specific_category($query) {
if ($query->is_home() && $query->is_main_query()) {
$query->set("cat", "-2");
}
}
add_action("pre_get_posts", "exclude_posts_from_specific_category");

@BradDalton, полный ответ был бы очень кстати. Я не совсем уверен, как это может сработать в моем случае.

Вы можете изменить существующий WP_Query с помощью pre_get_posts. http://codex.wordpress.org/Plugin_API/Action_Reference/pre_get_posts

Используйте хук pre_get_posts
чтобы исключить категории, которые не должны отображаться в цикле.
function exclude_posts_from_specific_category( $query ) {
if ( $query->is_home() && $query->is_main_query() ) {
$query->set( 'cat', '-2' );
}
}
add_action( 'pre_get_posts', 'exclude_posts_from_specific_category' );
Или создайте новый WP_Query
используя параметры категорий.
<?php
$args = array(
'category__not_in' => 2 ,
'category__in' => 4
);
$the_query = new WP_Query( $args );
if ( $the_query->have_posts() ) {
echo '<ul>';
while ( $the_query->have_posts() ) {
$the_query->the_post();
echo '<li>' . get_the_title() . '</li>';
}
echo '</ul>';
} else {
}
wp_reset_postdata();
Если нужно отображать записи только из одной категории, используйте архив категории. Смотрите Template Hierarchy
.

Ах, вот в чем была моя проблема. Я использовал cat__in
и cat__not_in
. Мне нужно было использовать полное слово category
в каждом параметре. Я также собираюсь поэкспериментировать с вашим другим методом.

Я отредактировал свой ответ, чтобы составить полный (?) список методов для этого.

Вы имеете в виду модульные тесты? Я просто провел быстрый smoke-тест, чтобы убедиться, что каждый метод в моем посте работает.

Пожалуйста, добавьте объяснение к вашему ответу: почему это решит проблему?

Эта статья должна прояснить этот вопрос
