Bootstrap

Vũ Thành Lâm

Content - Code - SEO - MMO
17/10/1979
Tây Mỗ - Nam Từ Liêm - Hà Nội
thanhlam19792003

Lamvt – Vũ Thành Lâm – bắt đầu Code 2005 Freelancer từ 2006 với hàng ngàn dự án lớn nhỏ cho nước ngoài và hàng trăm dự án web cho Việt Nam.

SEO thành công rất nhiều dự án lớn, độ khó cao.
MOD (Moderator) và Admin (Administraror) của nhiều diễn đàn về SEO và CODE web MMO tại Việt Nam
Dạy Lập trình Thiết kế Web và SEO Miễn phí 17++ Năm (Từ 2006 đến Nay)

Khi nào thì dùng WP_Query (), query_posts () và pre_get_posts

5/5 - (2 bình chọn)

Câu hỏi

Hôm qua tôi đã đọc bài You don’t know Query của @nacin’s và tôi cảm thấy bị loạn. Trước đó, tôi luôn dùng query_posts () bất cứ khi nào tôi cần dùng đến truy vấn, và bây giờ tôi đã biết đó là một cách làm sai. Giờ tôi đã biết rõ hơn một chút về cách dùng WP_Query (), nhưng vẫn còn một số vấn đề vướng mắc.

Khi nào thì dùng WP_Query (), query_posts () và pre_get_posts how-to-use-the-wp_query-function

Tôi nghĩ là tôi đã nắm rõ những điều sau đây:

Nếu tôi tạo vòng lặp bổ sung vào đâu đó trong một trang web – trong thanh bên (sidebar), ở chân trang, với bất kì các bài viết liên quan, ví dụ như vậy, tôi sẽ cần sử dụng WP_Query (). Tôi có thể sử dụng nó nhiều lần trong một trang mà không sợ có ảnh hưởng xấu gì. (Tôi hiểu như vậy có đúng không?)

Những điểm mà tôi chưa chắc chắn:

  1. Khi nào thì nên dùng pre_get_posts, khi nào thì dùng WP_Query (), @nacin’s? Tôi có nên sử dụng pre_get_posts cho mọi thứ không?
  2. Khi tôi muốn chỉnh sửa vòng lặp trong một trang mẫu – hay nói cách khác là tôi muốn chỉnh sửa một trang lưu trữ phân loại – thì tôi có cần phải bỏ đi phần if have_posts : while have_posts : the_post và viết WP_Query () của riêng mình không? Hay là tôi cần sửa đổi đầu ra bằng cách sử dụng pre_get_posts trong tệp functions.php của tôi?

tl;dr

Các quy tắc tl; dr tôi muốn rút ra từ đây là:

  1. Đừng bao giờ sử dụng query_posts.
  2. Khi chạy nhiều truy vấn trên một trang, hãy sử dụng WP_Query ()
  3. Khi sửa đổi một vòng lặp, hãy thực hiện điều này __________________.

Cảm ơn vì những lời khuyên rất thông minh.

Terry

Tái bút: Tôi đã nhìn thấy và đọc bài: When should you use WP_Query vs query_posts() vs get_posts()? Ở đó có nói đến một hướng khác là get_posts, nhưng không đề cập đến pre_get_posts.

saltcod

Có thể là bản sao của When should you use WP_Query vs query_posts() vs get_posts()? – dotancohen Jan 3 ’16 at 10:29

@saltcod, bây giờ đã khác rồi, WordPress đã được cải tiến hơn, tôi thêm một vài bình luận để so sánh với câu trả lời có thể chấp nhận được ở đây. – prosti Dec 28 ’16 at 1:46

Câu trả lời chính xác nhất

Tôi đồng ý với bạn rằng là:

Đừng bao giờ sử dụng query_posts.

pre_get_posts

pre_get_posts là một bộ lọc dùng để thay đổi bất kì truy vấn nào. Nó thường được sử dụng chỉ để thay đổi ‘truy vấn chính’:

add_action(‘pre_get_posts’,’wpse50761_alter_query’);
function wpse50761_alter_query($query){

if( $query->is_main_query() ){
//Do something to main query
}
}

(Tôi cũng sẽ kiểm tra xem is_admin () trả về false – mặc dù điều này có vẻ thừa thãi). Truy vấn chính xuất hiện trong các mẫu của bạn như là:

if( have_posts() ):
while( have_posts() ): the_post();
//The loop
endwhile;
endif;

Nếu bạn cảm thấy cần thiết chỉnh sửa lại vòng lặp này thì hãy sử dụng pre_get_posts. Ví dụ, nếu bạn đang có thói quen sử dụng query_posts () thì hãy dùng pre_get_posts để thay thế.

WP_Query 

Truy vấn chính (main query) là một ví dụ điển hình cho một đối tượng của WP_Query. Một ví dụ là WordPress sử dụng nó để quyết định xem phải sử dụng mẫu nào, và bất kỳ đối số nào được chuyển vào url (ví dụ: sự phân trang – pagination) đều được chuyển vào trường hợp đó của đối tượng WP_Query.

Đối với vòng lặp thứ cấp (ví dụ như trong thanh bên hoặc danh sách các bài viết liên quan) bạn sẽ muốn tạo một trường hợp riêng cho đối tượng WP_Query. Ví dụ:

$my_secondary_loop = new WP_Query(…);
if( $my_secondary_loop->have_posts() ):
while( $my_secondary_loop->have_posts() ): $my_secondary_loop->the_post();
//The secondary loop
endwhile;
endif;
wp_reset_postdata();

Hãy chú ý wp_reset_postdata (), bởi vì vòng lặp thứ cấp sẽ ghi đè lên biến $ post toàn cục, xác định ‘bài đăng hiện tại’. Về cơ bản, điều này đặt lại cho $ post chúng ta đang sử dụng.

get_posts()

Đây thực chất là một trình bao bọc cho một cá thể riêng biệt của một đối tượng WP_Query. Nó trả về một mảng các đối tượng bài viết. Các phương pháp được sử dụng trong vòng lặp ở trên không còn có sẵn cho bạn nữa. Đây không phải là một ‘Loop’, chỉ đơn giản là một mảng của đối tượng bài viết.

<ul>
<?php
global $post;
$args = array( ‘numberposts’ => 5, ‘offset’=> 1, ‘category’ => 1 );
$myposts = get_posts( $args );
foreach( $myposts as $post ) : setup_postdata($post); ?>
<li><a href=”<?php the_permalink(); ?>”><?php the_title(); ?></a></li>
<?php endforeach; wp_reset_postdata(); ?>
</ul>

Đáp lại các câu hỏi của bạn

  1. Sử dụng pre_get_posts để thay đổi truy vấn chính của bạn. Sử dụng một đối tượng WP_Query riêng biệt (phương thức 2) cho các vòng thứ cấp trong các trang mẫu.
  2. Nếu bạn muốn thay đổi truy vấn của vòng lặp chính, hãy sử dụng pre_get_posts.

Trả lời bởi Stephen Harris

Có trường hợp nào chỉ cần dùng get_posts() mà không phải là WP_Query không? – urok93 Aug 25 ’12 at 16:09

@drtanz – Có chứ, ví dụ như khi bạn không cần đánh số trang hoặc đính bài viết ở đầu. Trong những trường hợp như vậy thì get_posts() sẽ hiệu quả hơn. – Stephen Harris Aug 25 ’12 at 18:00

Nhưng làm vậy sẽ không thêm một truy vấn phụ khi chúng ta chỉ có thể sửa đổi pre_get_posts để sửa đổi truy vấn chính chứ? – urok93 Aug 26 ’12 at 20:54

@drtanz – Bạn đừng dùng get_posts() cho truy vấn chính, nó được sử dụng cho truy vấn phụ. – Stephen Harris Aug 26 ’12 at 22:42

@StephenHarris – Đúng vậy, nếu bạn dùng next_post() cho đối tượng thay vì the_post, bạn sẽ không phải làm việc với truy vấn toàn cục (global query) và sau đó không cần phải nhớ sử dụng wp_reset_postdata. – Privateer Sep 19 ’15 at 18:01

 

Tin mới nhất

Dù bạn dùng phiên bản WordPress với lưu lượng truy cập cao hay một blog nhỏ trên máy chủ chia...

VR PLUS (https://vrplus.vn/ ) Là một trong những dự án do Lamvt thực hiện trong thời gian gần đây. Như...

Trong một năm qua, chúng tôi đã xuất bản khoảng 79 bài viết SEO trên blog Ahrefs. Các bài viết...

Khám phá kĩ thuật viết nội dung SEO Nếu không có SEO, nội dung của bạn có thể bị chìm...

Các website về lĩnh vực làm đẹp cần phải có một thiết kế (design) hấp dẫn và bắt mắt. Điều...

Tin được yêu thích

Như đã nói, phần mềm chỉnh sửa video đang ngày càng chứng tỏ được tầm quan trọng của mình, nhất...

Nhiều bạn thắc mắc là sau khi cài đặt Plugin cho Google AMP thì làm thế nào để kiểm tra,...

Các trang web giáo dục và các trang web của chính phủ có một lợi thế hơn trong bảng xếp...

Nội dung là một trong 3 tiêu chí quan trọng để google đánh giá thứ hạng tìm kiếm cho website...

Thẻ <span> </span> Thẻ <span> là thẻ khá đặc biệt trong HTML, theo mặc định thì thẻ <span> được thêm...

Khách đang xem

  1. Bất kể bạn có muốn thừa nhận hay không, Facebook  rất quan trọng trong ngành công nghiệp kinh doanh Online....
    8 giây trước
  2. GoDaddy là một trong những thương hiệu nổi tiếng trong thị trường miền và web-hosting. GoDaddy phổ biến vì những lý do...
    18 giây trước
  3. “Content is King” nhưng Google mới là ông chủ! Nội dung chưa thực sự là vua. Vì sao vậy? "Content...
    10 giây trước
  4. Làm đẹp là khao khát, mong muốn chính đáng của mỗi người. Không chỉ riêng chị em phụ nữ, bất...
    20 giây trước
  5. Google AdSense và quảng cáo Facebook có giúp bạn kiếm ra tiền, tăng thu nhập cho một doanh nghiệp? Điều...
    15 giây trước
  6. Bạn đang có dự định tạo ra một trang Website đặt phòng du lịch trực tuyến? Nhất định không nên...
    6 giây trước
  7. 5 chiến lược quảng cáo số mà bất cứ doanh nghiệp nhỏ nào cũng nên quan tâm Một khi nắm...
    21 giây trước
  8. Làm thế nào để UP tốc độ trang (Page Speed) với Widget Defer? Có cách nào để hoãn một widget ở...
    9 giây trước
  9. Trong hai phần trước, chúng ta đã cùng tìm hiểu 50 thủ thuật giúp bạn tùy chỉnh trang web bán...
    18 giây trước
  10. Google đã giới thiệu một loại đơn vị quảng cáo AdSense mới gọi là 'Quảng cáo Native', làm tăng mối...
    13 giây trước