Phân loại tùy chỉnh WP_Query cho tất cả các điều khoản trong phân loại?


8

Có một cách dễ dàng để truy vấn cho bất kỳ bài viết được gắn thẻ với bất kỳ thuật ngữ từ một phân loại cụ thể?

Tôi biết kỹ thuật này:

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

Nhưng tôi muốn chuyển một ký tự đại diện thay cho term_slug hoặc có lẽ chỉ là một chuỗi rỗng. Sau đó, nó sẽ cung cấp cho tôi tất cả các bài đăng được gắn thẻ bởi bất kỳ thuật ngữ nào trong phân loại đó, không chỉ một thuật ngữ cụ thể.

Cảm ơn sự giúp đỡ của bạn, Dave

Câu trả lời:



22

Tôi đã gặp một tình huống tương tự Dave. Mã này đã lừa cho mục đích của tôi. Đây không phải là lựa chọn gọn gàng nhất trên thế giới nhưng nó thực hiện công việc tốt:

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

Hy vọng rằng điều này sẽ giúp bạn hoặc bất cứ ai khác gặp vấn đề.

Kevin


Điều này là vô cùng hữu ích cho tôi. Cảm ơn @kevinlearynet
Tyrun

Vẫn còn tương đối ngày hôm nay
user1676224

7

Một cái gì đó như thế này có thể hoạt động:

$ args = mảng (
    'post_type' => 'bài',
    'tax_query' => mảng (
        mảng(
            'phân loại' => 'your_custom_taxonomy',
            'toán tử' => 'EXISTS'
        ),
    ),
);
$ query = new WP_Query ($ args);

Về cơ bản, bạn đang yêu cầu bất kỳ bài đăng nào được gán cho bất kỳ thuật ngữ nào trong your_custom_taxonomy.


4

Xin chào @Dave Morris:

Bạn đã đúng, WordPress quyết định nếu bạn không có thuật ngữ họ sẽ bỏ qua phân loại của bạn.

ba (3) cách tiếp cận chính bạn có thể thử:

  1. Sử dụng một truy vấn SQL hoàn chỉnh với $wpdb->get_results(),

  2. Nhận danh sách $post->IDs cho tất cả các bài đăng trong phân loại của bạn và sau đó chuyển chúng bằng cách sử dụng 'post__id'đối số, hoặc

  3. Chú thích SQL được sử dụng bởiWP_Query một trong các hook cho phép bạn thêm SQL INNER JOINtham chiếu các bảng phân loại.

Tôi cố gắng tránh SQL hoàn chỉnh trong WordPress cho đến khi không thể giúp được hoặc đơn giản là trả về danh sách ID. Và trong trường hợp này, tôi sẽ tránh lấy danh sách $post-IDs để sử dụng với 'post__id'đối số vì nó có thể gặp vấn đề về hiệu năng và thậm chí cả vấn đề về bộ nhớ nếu bạn có nhiều bài đăng. Vì vậy, để lại cho chúng tôi với # 3.

Tôi đã tạo một lớp để mở rộngWP_Query được gọi là PostsByTaxonomysử dụng 'posts_join'hook. Bạn có thể thấy nó ở đây:

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

Bạn sẽ gọi lớp này như bạn thấy dưới đây. Đối số 'taxonomy'là bắt buộc nhưng bạn có thể vượt qua bất kỳ (tất cả?) Các tham số khác WP_Querymong đợi, chẳng hạn như 'posts_per_page':

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

Bạn có thể sao chép PostsByTaxonomylớp vào functions.phptệp của chủ đề hoặc bạn có thể sử dụng nó trong .phptệp của plugin bạn có thể đang viết.

Nếu bạn muốn kiểm tra nhanh, tôi đã đăng một phiên bản mã độc lập lên Gist mà bạn có thể tải xuống và sao chép vào thư mục gốc của máy chủ web của mình dưới dạng test.php, sửa đổi cho trường hợp sử dụng của bạn, sau đó yêu cầu từ trình duyệt của bạn bằng URL như http://example.com/test.php.

CẬP NHẬT

Để bỏ qua Bài viết dính từ các bài đăng có trong truy vấn, hãy thử điều này:

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

Hoặc nếu điều quan trọng với bạn là PostsByTaxonomylớp không bao giờ bao gồm các bài đăng dính bạn có thể đặt nó vào hàm tạo:

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

CẬP NHẬT 2

Sau khi đăng bài ở trên, tôi đã học được 'caller_get_posts' sẽ không được dùng nữa và 'ignore_sticky_posts'sẽ được sử dụng trong WordPress 3.1.


Mike, cảm ơn sự giúp đỡ của bạn. Tôi không thể làm cho nó hoạt động vì một số lý do. Nó không chỉ trả lại các bài đăng với các điều khoản được gán từ phân loại tùy chỉnh của tôi. Nó dường như luôn luôn trả lại các bài viết khác. Tuy nhiên, nó không trả về tất cả các bài đăng, vì vậy nó chắc chắn đang làm gì đó ... Tôi có thể sử dụng hàm $ query-> have_posts () để lặp lại không? Cả hai phương pháp dường như không hiệu quả với tôi.
Dave Morris

Ah, điều này thật thú vị. Tôi đã tìm thấy truy vấn trong nhật ký mysql nhận được hai bài đăng mà tôi mong đợi và nó hoạt động. Nhưng vì một số lý do, năm bài viết sẽ quay trở lại khi tôi lặp qua $ query-> bài viết. Điều khác duy nhất tôi nhận thấy là ngay sau khi truy vấn bài viết phân loại tùy chỉnh chạy, một truy vấn khác chạy lấy thêm ba bài đăng, bởi post_id của họ. Và sau đó tôi đoán tất cả năm bài viết được đưa vào một mảng kết quả.
Dave Morris

Tôi nghĩ rằng tôi đã tìm ra nó. Truy vấn tùy chỉnh này dường như bao gồm các bài đăng dính, mặc dù chúng không nằm trong phân loại tùy chỉnh đó. Bất kỳ ý tưởng về cách tôn vinh các bài viết dính đúng cách, hoặc ít nhất là để đưa chúng ra khỏi truy vấn cụ thể này? Cảm ơn, Dave
Dave Morris

Vâng, họ là "dính" , phải không? :) Đó là hành vi kỳ lạ, tôi nghĩ vậy, nhưng nếu bạn sử dụng caller_get_posts=1và chúng sẽ biến mất: codex.wordpress.org/Function_Reference/ tựa Hy vọng điều này sẽ giúp ích.
MikeSchinkel

Đó if(isset($query->posts_by_taxonomy))là một mẹo hay để kết hợp phương pháp hướng đối tượng với phương pháp hook của WordPress.
Jan Fabry

1

Bạn chỉ cần có thể thiết lập phân loại và phủ định để bao gồm một thuật ngữ ..

Ví dụ.

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

Điều này khá giống với truy vấn mà một kho lưu trữ phân loại thực hiện.


Điều đó không hiệu quả.
Dave Morris

Dòng 1432 của query.php kiểm tra xem phân loại HOẶC thuật ngữ có trống không, vì vậy bạn không thể không vượt qua một con sên ... Còn ý tưởng nào khác không?
Dave Morris

@ t31os - Đó cũng có thể là phản ứng đầu tiên; Tôi thực sự đã bị vấp ngã hơn một lần kể từ khi tôi quên. Nhưng @Dave Morris đã đúng; nếu nó không phải là một cặp phân loại / thuật ngữ thì WP_Queryhãy ném nó đi.
MikeSchinkel

6
@ t31os - Yup, WP_Querythật không may, không được thực hiện theo cách thanh lịch như vậy. Đó là gần 1200 dòng trường hợp đặc biệt được mã hóa cứng.
MikeSchinkel

3
"gần 1200 dòng trường hợp đặc biệt được mã hóa cứng." ... điều đó khiến tôi trở thành lol, đã phải +1 bình luận ...;)
t31os
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.