Câu trả lời muộn vì câu trả lời được đánh giá cao nhất sẽ phá vỡ truy vấn của bạn và đơn giản là không đúng ở một số điểm chính.
Các chính WP_Query và bộ lọc của nó
Đầu tiên, WordPress nội bộ sử dụng query_posts()
(một wrapper mỏng xung quanh WP_Query
mà không nên được sử dụng trong chủ đề hoặc bổ sung) để làm một WP_Query
. Đây WP_Query
là hoạt động như vòng lặp / truy vấn chính. Truy vấn này sẽ chạy qua rất nhiều bộ lọc và hành động cho đến khi chuỗi truy vấn SQL thực tế được xây dựng. Một trong số đó là pre_get_posts
. Những người khác posts_clauses
, posts_where
vv mà còn cho phép bạn ngăn chặn quá trình xây dựng chuỗi truy vấn.
Một cái nhìn sâu sắc về những gì xảy ra bên trong lõi
WordPress chạy wp()
hàm (in wp-includes/functions.php
), gọi $wp->main()
( $wp
là một đối tượng của lớp WP, được định nghĩa trong wp-includes/class-wp.php
). Điều này nói với WordPress về:
- Phân tích URL thành một đặc tả truy vấn bằng cách sử dụng
WP->parse_request()
- nhiều hơn về điều đó bên dưới.
- Đặt tất cả các biến is_ được sử dụng bởi Thẻ có điều kiện bằng cách sử dụng
$wp_query->parse_query()
( $wp_query
là một đối tượng của class WP_Query
, được xác định trong wp-includes/query.php
). Lưu ý rằng mặc dù tên của hàm này, trong trường hợp WP_Query->parse_query
này thực tế không thực hiện bất kỳ phân tích cú pháp nào cho chúng tôi, vì điều đó được thực hiện trước đó WP->parse_request()
.
- Chuyển đổi đặc tả truy vấn thành truy vấn cơ sở dữ liệu MySQL và chạy truy vấn cơ sở dữ liệu để lấy danh sách các bài đăng, trong chức năng WP_Query-> get_posts (). Lưu các bài đăng trong đối tượng $ wp_query sẽ được sử dụng trong Vòng lặp WordPress.
Codex nguồn
Phần kết luận
Nếu bạn thực sự muốn sửa đổi truy vấn chính, thì bạn có thể sử dụng nhiều bộ lọc khác nhau. Chỉ cần sử dụng $query->set( 'some_key', 'some_value' );
để thay đổi dữ liệu ở đó hoặc sử dụng $query->get( 'some_key' );
để truy xuất dữ liệu để thực hiện kiểm tra có điều kiện. Điều này sẽ giúp bạn không phải thực hiện truy vấn thứ hai, vì bạn chỉ thay đổi truy vấn SQL.
Nếu bạn phải thực hiện một truy vấn bổ sung , sau đó đi với một WP_Query
đối tượng. Điều này sẽ thêm một truy vấn khác vào DB.
Thí dụ
Vì các câu trả lời luôn hoạt động tốt hơn với một ví dụ, bạn ở đây có một câu trả lời rất hay (đạo cụ cho Brad Touesnard), chỉ đơn giản là mở rộng đối tượng cốt lõi và do đó khá dễ sử dụng lại (tạo một plugin từ nó):
class My_Book_Query extends WP_Query
{
function __construct( $args = array() )
{
// Forced/default args
$args = array_merge( $args, array(
'posts_per_page' => -1
) );
add_filter( 'posts_fields', array( $this, 'posts_fields' ) );
parent::__construct( $args );
}
public function posts_fields( $sql )
{
return "{$sql}, {$GLOBALS['wpdb']->terms}.name AS 'book_category'";
}
}
Sau đó, bạn có thể chạy truy vấn thứ hai / bổ sung như bạn có thể thấy trong ví dụ sau. Đừng quên đặt lại truy vấn của bạn sau đó.
$book_query = new My_Book_Query();
if ( $book_query->have_posts() )
{
while ( $book_query->have_posts() )
{
$book_query->the_post();
# ...do stuff...
} // endwhile;
wp_reset_postdata();
} // endif;