Пользовательская таксономия WP-запрос для всех терминов в таксономии?


Есть ли простой способ запросить любые записи, помеченные каким-либо термином из определенной таксономии?

Я знаю эту технику:

$custom_taxonomy_query = new WP_Query( 
 array(
  'taxonomy_name' => 'term_slug',
 )
);

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

Спасибо за вашу помощь, Дейв

Author: MikeSchinkel, 2010-11-05

5 answers

Оглядываясь назад, я сделал мэшап из предложений MikeSchinkel и t31os. Это можно добавить в существующие запросы на лету, но для этого нужен WordPress 3.1:

Плагин для получения RSS-канала для сообщений, содержащих любой термин из таксономии.

 1
Author: hakre, 2017-04-13 12:37:49

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

// Get all term ID's in a given taxonomy
$taxonomy = 'taxonomy_name';
$taxonomy_terms = get_terms( $taxonomy, array(
    'hide_empty' => 0,
    'fields' => 'ids'
) );

// Use the new tax_query WP_Query argument (as of 3.1)
$taxonomy_query = new WP_Query( array(
    'tax_query' => array(
        array(
            'taxonomy' => $taxonomy,
            'field' => 'id',
            'terms' => $taxonomy_terms,
        ),
    ),
) );

Надеюсь, это поможет вам или кому-либо еще, кто столкнулся с этой проблемой.

Кевин

 28
Author: Kevin Leary, 2011-12-05 18:02:26

Что-то вроде этого может сработать:

$args = array(
    'post_type' => 'post',
    'tax_query' => array(
        array(
            'taxonomy' => 'your_custom_taxonomy',
            'operator' => 'EXISTS'
        ),
    ),
);
$query = new WP_Query( $args );

Вы, по сути, просите любую должность, назначенную любому термину в рамках your_custom_taxonomy.

 9
Author: laurenfs132, 2016-01-29 18:44:00

Привет@Дейв Моррис:

Вы правы, WordPress решает, что если у вас нет термина, они просто проигнорируют вашу таксономию.

Существует три (3) основных подхода , которые вы могли бы попробовать:

  1. Используйте полный SQL-запрос с $wpdb->get_results(),

  2. Получите список $post->IDs для всех записей в вашей таксономии, а затем передайте их, используя аргумент 'post__id', или

  3. Аннотировать SQL, используемый WP_Query с помощью одного из крючков, которые позволяют вам добавить SQL INNER JOIN, ссылающийся на таблицы таксономии.

Я стараюсь избегать полного SQL в WordPress, пока либо с этим ничего не поделаешь, либо он просто возвращает список идентификаторов. И в этом случае я бы не стал извлекать список $post-ID для использования с аргументом 'post__id', потому что это может привести к проблемам с производительностью и даже проблемам с памятью, если у вас будет много сообщений. Таким образом, это оставляет нас с #3.

Я создал класс, чтобы расширить WP_Query называется PostsByTaxonomy, который использует крючок 'posts_join. Вы можете увидеть это здесь:

class PostsByTaxonomy extends WP_Query {
  var $posts_by_taxonomy;
  var $taxonomy;
  function __construct($args=array()) {
    add_filter('posts_join',array(&$this,'posts_join'),10,2);
    $this->posts_by_taxonomy = true;
    $this->taxonomy = $args['taxonomy'];
    unset($args['taxonomy']);
    parent::query($args);
  }
  function posts_join($join,$query) {
    if (isset($query->posts_by_taxonomy)) {
      global $wpdb;
      $join .=<<<SQL
INNER JOIN {$wpdb->term_relationships} ON {$wpdb->term_relationships}.object_id={$wpdb->posts}.ID
INNER JOIN {$wpdb->term_taxonomy} ON {$wpdb->term_taxonomy}.term_taxonomy_id={$wpdb->term_relationships}.term_taxonomy_id
  AND {$wpdb->term_taxonomy}.taxonomy='{$this->taxonomy}'
SQL;
    }
    return $join;
  }
}

Вы бы назвали этот класс так, как видите ниже. Аргумент 'taxonomy' является обязательным , но вы можете передать любой (все?) из других параметров, которые WP_Query также ожидает, например 'posts_per_page':

$query = new PostsByTaxonomy(array(
  'taxonomy' => 'category',
  'posts_per_page' => 25,
));
foreach($query->posts as $post) {
  echo " {$post->post_title}\n";
}

Вы можете скопировать класс PostsByTaxonomy в файл functions.php вашей темы или использовать его в файле .php плагина, который вы, возможно, пишете.

Если вы хотите быстро протестировать его Я опубликовал автономная версия кода чтобы понять, что вы можете загрузить и скопировать в корневой каталог вашего веб-сервера как test.php, измените для вашего варианта использования, а затем запросите в своем браузере, используя URL-адрес, например http://example.com/test.php.

ОБНОВЛЕНИЕ

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

$query = new PostsByTaxonomy(array(
  'taxonomy' => 'category',
  'posts_per_page' => 25,
  'caller_get_posts' => true,
));

Или, если для вас важно, чтобы класс PostsByTaxonomy никогда не включал липкие сообщения, вы могли бы поместить его в конструктор:

  function __construct($args=array()) {
    add_filter('posts_join',array(&$this,'posts_join'),10,2);
    $this->posts_by_taxonomy = true;
    $this->taxonomy = $args['taxonomy'];
    $args['caller_get_posts'] = true     // No Sticky Posts
    unset($args['taxonomy']);
    parent::query($args);
  }

ОБНОВЛЕНИЕ 2

После публикации вышеизложенного я узнал, что "caller_get_posts" устареет и 'ignore_sticky_posts' будет использоваться в WordPress 3.1.

 4
Author: MikeSchinkel, 2010-11-07 20:51:41

Вы должны просто иметь возможность установить таксономию и отрицать, чтобы включить термин..

Например.

<?php
$your_query = new WP_query;
$your_query->query( array( 'taxonomy' => 'your-taxonomy-name' ) );
?>

, Что в значительной степени будет совпадать с запросом, выполняемым архивом таксономии.

 1
Author: t31os, 2010-11-05 23:33:32