Как выбрать записи из одной категории, но исключить записи из другой категории?

14 июл. 2014 г., 12:12:21
Просмотры: 14K
Голосов: 2

Я пытаюсь выбрать записи, которые относятся к категории с 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            // Смещение
));

Однако выборка работает неправильно. Что я делаю не так?

1
Комментарии

cat__in и cat__not_in не являются допустимыми параметрами. Проверьте допустимые параметры категорий в WP_Query. Вы можете просто передать 'cat'=>4 в аргументы, чтобы получить записи только из категории 4. Или, как предложил Brad, используйте pre_get_posts и передайте те же параметры туда

Pieter Goosen Pieter Goosen
14 июл. 2014 г. 13:09:19
Все ответы на вопрос 3
3

Оказывается, это можно сделать 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");
14 июл. 2014 г. 12:20:29
Комментарии

Или вы можете использовать pre_get_posts

Brad Dalton Brad Dalton
14 июл. 2014 г. 12:29:23

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

User User
14 июл. 2014 г. 12:36:41

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

Brad Dalton Brad Dalton
14 июл. 2014 г. 13:38:57
5

Используйте хук 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.

14 июл. 2014 г. 13:41:41
Комментарии

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

User User
14 июл. 2014 г. 21:05:45

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

User User
14 июл. 2014 г. 21:34:07

Это отлично, @naomik. Вы тоже тестировали свой код?

Brad Dalton Brad Dalton
15 июл. 2014 г. 00:22:52

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

User User
15 июл. 2014 г. 02:38:20

Давайте оставим комментарии здесь, так как это затягивается, но я просто предлагаю вам протестировать все фрагменты кода в вашей теме.

Brad Dalton Brad Dalton
15 июл. 2014 г. 11:23:42
4
-3

Предположим, у вас есть записи с ID категории 4.

query_posts('cat=4');
  while (have_posts()) : the_post();
      the_content();
  endwhile;
14 июл. 2014 г. 12:19:34
Комментарии

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

fuxia fuxia
14 июл. 2014 г. 12:23:00

Вы никогда не должны использовать query_posts, никогда

Pieter Goosen Pieter Goosen
14 июл. 2014 г. 13:04:57

причина, по которой нельзя использовать query_posts?

jojo jojo
14 июл. 2014 г. 13:27:10

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

Pieter Goosen Pieter Goosen
14 июл. 2014 г. 13:49:31