Taksonomi Kustom WP_Query untuk Semua Persyaratan dalam Taksonomi?

8

Apakah ada cara mudah untuk meminta posting yang ditandai dengan istilah apa pun dari taksonomi tertentu?

Saya tahu teknik ini:

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

Tapi saya ingin memberikan wildcard sebagai ganti term_slug, atau mungkin hanya string kosong. Maka itu akan memberi saya semua posting yang ditandai oleh istilah apa pun dalam taksonomi itu, bukan hanya satu istilah tertentu.

Terima kasih atas bantuan Anda, Dave

Dave Morris
sumber

Jawaban:

23

Saya mengalami situasi yang sama Dave. Kode ini melakukan trik untuk tujuan saya. Ini bukan opsi yang paling ramping di dunia tetapi itu berfungsi dengan baik:

// 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,
        ),
    ),
) );

Semoga ini membantu Anda atau siapa pun yang mengalami masalah ini.

Kevin

Kevin Leary
sumber
Ini sangat membantu saya. Terima kasih @kevinlearynet
Tyrun
Masih relatif hari ini
user1676224
7

Sesuatu seperti ini mungkin bekerja:

$ args = array (
    'post_type' => 'post',
    'tax_query' => array (
        Himpunan(
            'taxonomy' => 'your_custom_taxonomy',
            'operator' => 'ADA'
        ),
    ),
);
$ query = WP_Query baru ($ args);

Anda pada dasarnya meminta setiap pos yang ditetapkan untuk istilah apa pun dalam your_custom_taxonomy.

laurenfs132
sumber
4

Hai @ Dave Morris:

Anda benar, WordPress memutuskan jika Anda tidak memiliki istilah mereka hanya akan mengabaikan taksonomi Anda.

Ada tiga (3) pendekatan utama yang bisa Anda coba:

  1. Gunakan kueri SQL lengkap dengan $wpdb->get_results(),

  2. Dapatkan daftar $post->IDs untuk semua posting di taksonomi Anda dan kemudian sampaikan dengan menggunakan 'post__id'argumen, atau

  3. Buat anotasi SQL yang digunakan olehWP_Query dengan salah satu kait yang memungkinkan Anda menambahkan SQL INNER JOINreferensi tabel taksonomi.

Saya mencoba untuk menghindari SQL lengkap di WordPress sampai tidak dapat membantu atau hanya mengembalikan daftar ID. Dan dalam hal ini saya akan menghindari menarik daftar $post-IDs untuk digunakan dengan 'post__id'argumen karena dapat mengalami masalah kinerja dan bahkan masalah memori jika Anda memiliki banyak posting. Sehingga meninggalkan kita dengan # 3.

Saya telah membuat kelas untuk memperpanjang yangWP_Query disebut PostsByTaxonomyyang menggunakan 'posts_join'kait. Anda bisa melihatnya di sini:

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;
  }
}

Anda akan memanggil kelas ini seperti yang Anda lihat di bawah. Argumen 'taxonomy'ini diperlukan tetapi Anda dapat melewati (semua?) Dari parameter lain yang WP_Querymengharapkan juga, seperti 'posts_per_page':

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

Anda dapat menyalin PostsByTaxonomykelas ke functions.phpfile tema Anda , atau Anda dapat menggunakannya dalam .phpfile plugin yang mungkin Anda tulis.

Jika Anda ingin mengujinya dengan cepat, saya telah memposting versi mandiri dari kode ke Gist yang dapat Anda unduh dan salin ke root server web Anda sebagai test.php, modifikasi untuk kasus penggunaan Anda, dan kemudian permintaan dari browser Anda menggunakan URL seperti http://example.com/test.php.

MEMPERBARUI

Untuk menghilangkan Posting Lengket dari pos yang termasuk dalam kueri, coba ini:

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

Atau jika penting bagi Anda bahwa PostsByTaxonomykelas tidak pernah menyertakan posting tempel Anda bisa memasukkannya ke dalam konstruktor:

  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);
  }

PEMBARUAN 2

Setelah memposting di atas saya belajar 'caller_get_posts' akan usang dan 'ignore_sticky_posts'akan digunakan di WordPress 3.1.

MikeSchinkel
sumber
Mike, Terima kasih atas bantuan Anda. Saya tidak bisa membuatnya bekerja karena suatu alasan. Itu tidak hanya mengembalikan pos dengan ketentuan yang ditetapkan dari taksonomi khusus saya. Tampaknya selalu mengembalikan pos lainnya. Namun, itu tidak mengembalikan semua posting, jadi pasti melakukan sesuatu ... Apakah saya dapat menggunakan fungsi $ query-> have_posts () untuk beralih? Kedua metode itu tampaknya tidak cocok untuk saya.
Dave Morris 6-10
Ah, ini menarik. Saya menemukan kueri dalam log mysql yang mendapatkan dua posting yang saya harapkan, dan itu berfungsi. Tetapi karena suatu alasan, lima postingan akan kembali ketika saya mengulang $ post-> postingan. Satu-satunya hal lain yang saya perhatikan adalah bahwa langsung setelah kueri pos taksonomi kustom berjalan, kueri lain berjalan yang mengambil tiga pos lainnya, oleh post_id mereka. Dan kemudian saya kira semua lima posting dimasukkan ke dalam satu array hasil.
Dave Morris 6-10
Saya pikir saya sudah menemukannya. Kueri khusus ini tampaknya menyertakan pos tempel, meskipun tidak termasuk dalam taksonomi khusus tersebut. Adakah ide tentang cara menghormati posting yang lengket dengan benar, atau setidaknya untuk mengeluarkannya dari permintaan khusus ini? Terima kasih, Dave
Dave Morris 6-10
Yah mereka "lengket" , kan? :) Ini perilaku yang aneh, saya pikir, tetapi jika Anda menggunakan caller_get_posts=1dan mereka harus pergi: codex.wordpress.org/Function_Reference/… Semoga ini bisa membantu.
MikeSchinkel
Itu if(isset($query->posts_by_taxonomy))adalah trik yang bagus untuk menggabungkan metodologi berorientasi objek dengan metodologi kait WordPress.
Jan Fabry
1

Anda seharusnya bisa mengatur taksonomi dan meniadakan untuk memasukkan istilah ..

Misalnya.

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

Yang hampir sama dengan permintaan yang dilakukan oleh arsip taksonomi.

t31os
sumber
Itu tidak berhasil.
Dave Morris
Baris 1432 dari query.php memeriksa apakah taksonomi ATAU istilah kosong, jadi Anda tidak boleh tidak lulus siput ... Ada gagasan lain?
Dave Morris
@ t31os - Itu mungkin reaksi pertama juga; Saya sebenarnya telah tersandung olehnya lebih dari sekali sejak saya terus lupa. Tapi @Dave Morris benar; jika itu bukan pasangan taksonomi / istilah maka WP_Querybuang saja.
MikeSchinkel
6
@ t31os - Yup, WP_Querysayangnya tidak diimplementasikan dengan cara yang elegan. Ini hampir 1.200 baris kasus khusus hard-coded.
MikeSchinkel
3
"Hampir 1.200 baris kotak khusus yang dikode keras." ... yang membuat saya tertawa, harus memberi +1 pada komentar ...;)
t31os