Một số nghi ngờ về cách truy vấn chính và truy vấn tùy chỉnh hoạt động trong chủ đề tùy chỉnh này?


20

Tôi khá mới trong phát triển chủ đề WordPress và tôi không thích PHP (tôi đến từ Java và C #) và có tình huống sau trong chủ đề tùy chỉnh này

Như bạn có thể thấy trong trang chủ, lần đầu tiên tôi hiển thị một phần (có tên là Articoli trong evidenza ) có chứa các bài đăng nổi bật (tôi đã triển khai nó bằng một thẻ cụ thể) và bên dưới nó có một khu vực khác (có tên là Ultimi Articoli ) có chứa bài đăng mới nhất đó không phải là bài viết nổi bật.

Để làm điều đó tôi sử dụng mã này:

<section id="blog-posts">

<header class="header-sezione">
        <h2>Articoli in evidenza</h2>
</header>

<!--<?php query_posts('tag=featured');?>-->

<?php
    $featured = new WP_Query('tag=featured');

    if ($featured->have_posts()) : 
            while ($featured->have_posts()) : $featured->the_post();
            /*
             * Include the post format-specific template for the content. If you want to
             * use this in a child theme, then include a file called called content-___.php
             * (where ___ is the post format) and that will be used instead.
             */
                 get_template_part('content', get_post_format());

             endwhile;
        wp_reset_postdata();
    else :
        // If no content, include the "No posts found" template.
        get_template_part('content', 'none');

    endif;
    ?>


<header class="header-sezione">
    <h2>Ultimi Articoli</h2>
</header>

<?php
// get the term using the slug and the tag taxonomy
$term = get_term_by( 'slug', 'featured', 'post_tag' );
// pass the term_id to tag__not_in
query_posts( array( 'tag__not_in' => array ( $term->term_id )));
?>

<?php
    if (have_posts()) :
        // Start the Loop.
        while (have_posts()) : the_post();

            /*
             * Include the post format-specific template for the content. If you want to
             * use this in a child theme, then include a file called called content-___.php
             * (where ___ is the post format) and that will be used instead.
             */
            get_template_part('content', get_post_format());

        endwhile;
    else :
        // If no content, include the "No posts found" template.
        get_template_part('content', 'none');

    endif;
    ?>

</section>

Nó hoạt động tốt, nhưng tôi có một số nghi ngờ về chất lượng của giải pháp này và cách chính xác nó hoạt động.

Để chọn tất cả các bài đăng nổi bật , tôi sử dụng dòng này tạo một WP_Queryđối tượng mới xác định truy vấn có thẻ cụ thể featured:

$featured = new WP_Query('tag=featured');

Sau đó, tôi lặp lại kết quả truy vấn này bằng have_posts()phương pháp của nó .

Vì vậy, từ những gì tôi đã hiểu, đây không phải là truy vấn chính của WordPress, nhưng nó là một truy vấn mới do tôi tạo ra. Từ những gì tôi hiểu, tốt hơn là tạo một truy vấn mới (như đã hoàn thành) và không sử dụng truy vấn chính khi tôi muốn thực hiện loại hoạt động này.

Là sự thật, hay tôi đang thiếu một cái gì đó? Nếu đó là sự thật, bạn có thể giải thích cho tôi, tại sao tốt hơn là tạo một truy vấn tùy chỉnh mới và không sửa đổi truy vấn chính Wordpress?

Ok, đang diễn ra. Tôi hiển thị tất cả các bài đăng không có thẻ 'đặc trưng'. Để làm điều này, tôi sử dụng đoạn mã này, ngược lại, sửa đổi truy vấn chính:

    <?php
    // get the term using the slug and the tag taxonomy
    $term = get_term_by( 'slug', 'featured', 'post_tag' );
    // pass the term_id to tag__not_in
    query_posts( array( 'tag__not_in' => array ( $term->term_id )));
    ?>

    <?php
        if (have_posts()) :
            // Start the Loop.
            while (have_posts()) : the_post();
                get_template_part('content', get_post_format());

            endwhile;
        else :
            // If no content, include the "No posts found" template.
            get_template_part('content', 'none');

        endif;
        ?>

Vì vậy, tôi nghĩ rằng, điều này là khá kinh khủng. Có thật không?

CẬP NHẬT:

Để thực hiện thao tác tương tự, tôi đã tìm thấy hàm này (trong câu trả lời tuyệt vời bên dưới) mà tôi đã thêm vào hàm.php

function exclude_featured_tag( $query ) {
    if ( $query->is_home() && $query->is_main_query() ) {
        $query->set( 'tag__not_in', 'array(ID OF THE FEATURED TAG)' );
    }
}
add_action( 'pre_get_posts', 'exclude_featured_tag' );

Hàm này có một hook được gọi sau khi đối tượng biến truy vấn được tạo, nhưng trước khi truy vấn thực tế được chạy.

Vì vậy, từ những gì tôi đã hiểu, nó lấy một đối tượng truy vấn làm tham số đầu vào và sửa đổi (thực sự là bộ lọc) bằng cách chọn tất cả các bài đăng không bao gồm một thẻ cụ thể (trong trường hợp của tôi là các featuredbài đăng thẻ)

Vì vậy, làm cách nào tôi có thể sử dụng truy vấn trước đó (truy vấn được sử dụng để hiển thị các bài đăng nổi bật) với chức năng này để chỉ hiển thị các bài đăng không nổi bật trong chủ đề của tôi? Hay tôi phải tạo một truy vấn mới?

Câu trả lời:


33

Câu hỏi thực tế của bạn về cơ bản là khi nào nên chạy truy vấn tùy chỉnh và khi nào nên sử dụng truy vấn chính. Hãy chia nó thành ba phần

PHẦN MỘT

Khi nào nên chạy truy vấn tùy chỉnh (Đây không phải là danh sách dứt khoát)

  • Để tạo thanh trượt nội dung tùy chỉnh

  • Để tạo một khu vực nội dung nổi bật trong một trang

  • Trên mẫu page.php nếu bạn cần hiển thị bài viết

  • Nếu bạn yêu cầu nội dung tùy chỉnh trên trang đầu tĩnh

  • Hiển thị bài viết liên quan, phổ biến hoặc thông tin

  • Bất kỳ nội dung phụ hoặc bổ sung nào khác ngoài phạm vi của truy vấn chính

Khi nào sử dụng truy vấn chính.

Để hiển thị nội dung chính trên

  • Trên trang chủ của bạn và trang được đặt làm trang blog trong phần phụ trợ

  • Tất cả các trang lưu trữ bao gồm các mẫu như archive.php, category.php, Author.php, taxonomy.php, tag.php và date.php

  • CẬP NHẬT: Hiển thị nội dung tùy chỉnh trên các trang thật và trang trước tĩnh ( xem Sử dụng pre_get_posts trên trang thật và trang trước tĩnh )

PHẦN HAI

Để chọn tất cả các bài đăng nổi bật, tôi sử dụng dòng này để tạo một đối tượng WP_Query mới xác định truy vấn có thẻ cụ thể đặc trưng:

Vì vậy, từ những gì tôi đã hiểu, đây không phải là truy vấn chính của Solitaire mà nó là một truy vấn mới do tôi tạo ra. Từ những gì tôi đã hiểu, tốt hơn là tạo một truy vấn mới (như đã hoàn thành) và không sử dụng truy vấn chính khi tôi muốn thực hiện loại hoạt động này

Chính xác. Điều này rơi ra khỏi phạm vi cho truy vấn chính. Đây là nội dung thứ cấp hoặc bổ sung không thể được tạo bằng truy vấn chính. Bạn NÊN LUÔN sử dụng WP_Queryhoặc get_postsđể tạo các truy vấn tùy chỉnh của mình.

KHÔNG BAO GIỜ SỬ DỤNG query_posts để tạo các truy vấn tùy chỉnh hoặc thậm chí bất kỳ truy vấn nào khác. Tôi nhấn mạnh.

Lưu ý: Chức năng này không có nghĩa là được sử dụng bởi các plugin hoặc chủ đề. Như được giải thích sau, có các tùy chọn tốt hơn, hiệu quả hơn để thay đổi truy vấn chính. query_posts () là cách quá đơn giản và có vấn đề để sửa đổi truy vấn chính của trang bằng cách thay thế nó bằng phiên bản mới của truy vấn. Đó là không hiệu quả (chạy lại các truy vấn SQL) và sẽ hoàn toàn thất bại trong một số trường hợp (đặc biệt là thường xuyên khi xử lý phân trang bài viết).

Tiến lên

Ok, tiếp tục tôi hiển thị tất cả các bài đăng không có thẻ đặc trưng, ​​để làm điều này tôi sử dụng đoạn mã này mà ngược lại sửa đổi truy vấn chính:

query_posts( array( 'tag__not_in' => array ( $term->term_id )));

Vì vậy, tôi nghĩ rằng điều này là khá kinh khủng. Có thật không?

Đó là tất cả sai và tuyên bố của bạn là không may đúng. Như đã nói, KHÔNG BAO GIỜ sử dụng query_posts. Nó chạy một truy vấn hoàn toàn mới, điều này không tốt cho hiệu năng và hầu hết các trường hợp phá vỡ phân trang là một phần không thể thiếu của truy vấn chính để phân trang hoạt động chính xác.

Đây là nội dung chính của bạn, vì vậy bạn nên sử dụng truy vấn chính với vòng lặp mặc định, trông giống như thế này và đây là tất cả những gì bạn cần

<?php
    if (have_posts()) :
        // Start the Loop.
        while (have_posts()) : the_post();

            get_template_part('content', get_post_format());

        endwhile;
    else :
        // If no content, include the "No posts found" template.
        get_template_part('content', 'none');

    endif;
?>

Bạn hoàn toàn có thể thoát khỏi phần này, xóa nó, ghi nó và quên nó đi

<?
// get the term using the slug and the tag taxonomy
$term = get_term_by( 'slug', 'featured', 'post_tag' );
// pass the term_id to tag__not_in
query_posts( array( 'tag__not_in' => array ( $term->term_id )));
?>

OK, một khi bạn đã làm điều đó, bạn sẽ thấy các bài đăng từ thẻ tính năng xuất hiện trong trang chủ của bạn bằng cách sử dụng truy vấn chính và vòng lặp mặc định.

Cách chính xác để xóa thẻ này khỏi trang chủ là với pre_get_posts. Đây là cách thích hợp để thay đổi truy vấn chính và hook bạn nên luôn sử dụng để thực hiện các thay đổi cho vòng lặp nội dung chính của mình.

Vì vậy, mã với pre_get_postslà chính xác và đây là chức năng mà bạn nên sử dụng. Chỉ có một điều, luôn luôn kiểm tra xem bạn không ở trên trang quản trị vì cũng pre_get_poststhay đổi phần cuối. Vì vậy, đây là mã thích hợp để sử dụng trong các functions.phpbài viết được remove Tagged đặc trưng từ trang chủ

add_action( 'pre_get_posts', 'exclude_featured_tag' );
function exclude_featured_tag( $query ) 
{
    if (    !is_admin() 
         && $query->is_home() 
         && $query->is_main_query() 
    ) {
        $query->set( 'tag__not_in', [ID OF THE FEATURED TAG] );
    }
}

MỘT PHẦN BA

Tài liệu đọc thêm sẽ hữu ích trong tương lai


Hân hạnh. Thật vui khi bạn thấy nó hữu ích. Enjou :-)
Pieter Goosen

Wow, khá là một câu trả lời! Tôi đang thiếu một thông tin quan trọng mặc dù: làm thế nào để tôi nói với WP "đây là trang bài viết" bên cạnh trang bài viết chính? Giả sử tôi muốn một danh sách các bài đăng có danh mục 10,11,12 và một danh sách khác có danh mục 13,14,15. Tôi thấy làm thế nào tôi có thể sử dụng pre_get_posts để đưa các danh mục vào truy vấn chính, nhưng làm cách nào tôi có thể nói với WP để hiển thị đó dưới dạng danh sách các bài đăng với phân trang thích hợp? Tôi có thực sự phải theo dõi câu trả lời mở rộng của bạn ở đây wordpress.stackexchange.com/a/215027/74134 vì đó là Trang không? Chắc chắn WordPress thực sự cho phép nhiều danh sách blog trong một trang web?
Mark Berry
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.