Деякі сумніви щодо того, як працює головний запит та користувацький запит у цій спеціальній темі?


20

Я досить новий в розробці тем WordPress, і я не так в PHP (я прийшов з Java та C #) і маю таку ситуацію в цій спеціальній темі

Як ви бачите на домашній сторінці, я спочатку показую розділ (з назвою Articoli in evidenza ), що містить представлені публікації (я реалізував це за допомогою певного тегу), а під ним є ще одна область (названа Ultimi Articoli ), яка містить останню публікацію це не рекомендований пост.

Для цього я використовую цей код:

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

Це прекрасно працює, але я маю певні сумніви щодо якості цього рішення та як саме воно працює.

Для вибору всіх представлених публікацій я використовую цей рядок, який створює новий WP_Queryоб’єкт, який визначає запит, що містить конкретний тег featured:

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

Потім я повторюю цей результат запиту, використовуючи його have_posts()метод.

Отже, з того, що я зрозумів, це не основний запит WordPress, але це новий запит, створений мною. З того, що я розумію, краще створити новий запит (як зроблено), а не використовувати основний запит, коли я хочу виконати подібну операцію.

Це правда, чи я щось пропускаю? Якщо це правда, чи можете ви пояснити мені, чому краще створити новий спеціальний запит, а не змінювати основний запит Wordpress?

Гаразд, продовжуємо. Я показую всі публікації, які не мають тегу "показаний". Для цього я використовую цей фрагмент коду, який, навпаки, змінює основний запит:

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

Тому я думаю, це досить жахливо. Це правда?

ОНОВЛЕННЯ:

Щоб виконати ту саму операцію, я знайшов цю функцію (у великій відповіді нижче), яку я додав у function.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' );

Ця функція має гачок, який викликається після створення об'єкта змінної запиту, але перед запуском фактичного запиту.

Отже, з того, що я зрозумів, він приймає об’єкт запиту як вхідний параметр і змінює (фактично фільтрує) його, вибираючи всі повідомлення, виключаючи конкретний тег (у моєму випадку featuredповідомлення про теги)

Отже, як я можу використовувати попередній запит (той, який використовується для показу популярних публікацій) за допомогою цієї функції, щоб відображати лише непопулярні публікації в моїй темі? Або мені потрібно створити новий запит?

Відповіді:


33

Ваше фактичне запитання - це в основному, коли запустити спеціальний запит і коли використовувати основний запит. Дозволяємо розбити її на три частини

ЧАСТИНА ПЕРША

Коли запускати спеціальний запит (це не остаточний список)

  • Щоб створити користувацькі повзунки для вмісту

  • Щоб створити на сторінці відображену область вмісту

  • На шаблонах page.php, якщо вам потрібно відображати повідомлення

  • Якщо вам потрібен спеціальний вміст на статичній титульній сторінці

  • Відображення пов’язаних, популярних чи інформаційних публікацій

  • Будь-який інший вторинний або додатковий вміст за межами основного запиту

Коли використовувати основний запит.

Щоб відобразити основний вміст

ЧАСТИНА ДРУГА

Для вибору всіх представлених публікацій я використовую цей рядок, який створює новий об'єкт WP_Query, який визначає запит, що містить конкретний тег:

Отже, з того, що я зрозумів, це не основний запит WordPres, але це новий запит, створений мною. З того, що я зрозумів, краще створити новий запит (як зроблено), а не використовувати основний запит, коли я хочу виконувати такі операції

Правильно. Це не виходить для основного запиту. Це вторинний або додатковий вміст, який неможливо створити за допомогою основного запиту. Ви завжди повинні використовувати або WP_Queryчи get_postsстворювати свої власні запити.

НІКОЛИ НЕ ВИКОРИСТОВУЙТЕ query_posts для створення спеціальних запитів або навіть будь-яких інших запитів. Мій акцент.

Примітка. Ця функція не призначена для використання плагінами або темами. Як було пояснено пізніше, існують кращі, ефективніші варіанти зміни основного запиту. query_posts () - надмірно спрощений та проблемний спосіб змінити головний запит сторінки, замінивши його новим екземпляром запиту. Він неефективний (повторно виконує запити SQL) і відмовиться відмовитись у деяких обставинах (особливо це стосується пагінації повідомлень).

Жити далі

Гаразд, я продовжую показувати всі публікації, на яких не розміщений тег, для цього я використовую цей фрагмент коду, який навпаки змінює основний запит:

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

Тому я вважаю, що це досить жахливо. Це правда?

Це все неправильно, і ваше твердження, на жаль, вірно. Як говорилося раніше, НІКОЛИ не використовуйте query_posts. Він виконує повний новий запит, що погано спрацьовує, і він у більшості випадків порушує сторінку, що є невід'ємною частиною основного запиту для правильної роботи сторінки.

Це ваш основний вміст, тому вам слід використовувати основний запит із циклом за замовчуванням, який повинен виглядати так, і це все, що вам потрібно

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

Ви можете повністю позбутися цієї частини, видалити, спалити і забути про неї

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

Добре, щойно ви зробите це, ви побачите, що публікації з тегу функцій відображаються на вашій домашній сторінці, використовуючи основний запит і цикл за замовчуванням.

Правильний спосіб видалення цього тегу з домашньої сторінки - за допомогою pre_get_posts. Це правильний спосіб змінити основний запит і гачок, який ви завжди повинні використовувати для внесення змін до вашого основного циклу вмісту.

Отже, код з pre_get_postsправильний, і це функція, яку ви повинні використовувати. Тільки одне, завжди робіть перевірку, чи не перебуваєте ви на сторінці адміністратора, оскільки це також pre_get_postsзмінює задній край. Так що це правильний код для використання в functions.phpдля видалення повідомлень з тегами ознак з домашньої сторінки

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

ЧАСТИНА ТРИ

Додатковий матеріал для читання, який буде корисний у майбутньому


Моє задоволення. Радий, що ти вважаєш його корисним. Enjou :-)
Пітер Гусен

Вау, цілком відповідь! Хоча мені не вистачає однієї критичної інформації: як я можу сказати WP "це сторінка повідомлень", окрім основної сторінки повідомлень? Скажімо, я хочу один список публікацій з категоріями 10,11,12 та інший список з категоріями 13,14,15. Я бачу, як я міг би використовувати pre_get_posts для введення категорій в основний запит, але як я можу сказати WP винести це як список публікацій з належною пагінацією? Чи дійсно мені слід дотримуватися вашої великої відповіді тут wordpress.stackexchange.com/a/215027/74134, оскільки це Сторінка? Напевно WordPress споконвічно допускає декілька списків блогів на сайті?
Марк Беррі
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.