следует ли избегать сообщений с запросами()?


Я читаю, что query_posts() следует избегать в пользу wp_query() и pre_get_posts(). Я не уверен в том, чтобы возиться с Циклом, и не до конца понимаю кодекс.

Использует ли приведенный ниже код query_posts()? Если да, и поскольку query_posts() следует избегать, можете ли вы предложить метод, который не использует query_posts(), но все равно выполняет то же самое?

Этот код в functions.php используется для сортировки сообщений по случайному или по цене.

function my_custom_query($query){
 if ( $query->is_home() && $query->is_main_query() ) {

   $sort= $_GET['sort'];

   if($sort == "pricelow"){
     $query->set( 'meta_key', 'price' );
     $query->set( 'orderby', 'meta_value_num' );
     $query->set( 'order', 'ASC' );
    }

  if($sort == "random"){
     $query->set( 'orderby', 'rand' );
    }

 }
}
add_action( 'pre_get_posts', 'my_custom_query' );

.
Ссылка A (Случайная) и Ссылка B (Цена) размещены в мое меню с помощью этого кода. Таким образом, посетитель веб-сайта может сортировать сообщения, просто нажав на ссылку.

<a href="http://website.com/?sort=A">Random</a>
<a href="http://website.com/?sort=B">Price</a>
Author: Anoop Asok, 2014-08-31

2 answers

Я сделал очень подробное объяснение по этой самой теме на WPSE, и ради ценности и пользы, которые это может иметь для пользователей SO, вот полный пост, скопированный с этого вопроса на WPSE. Для интереса, вот ссылка на полный пост на WPSE: Некоторые сомнения в том, как работает основной запрос и пользовательский запрос в этой пользовательской теме?

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

ЧАСТЬ ПЕРВАЯ

Когда запускать пользовательский запрос (это не окончательный список)

  • Для создания пользовательских ползунков содержимого

  • Чтобы создать область избранного контента на странице

  • На page.php шаблоны, если вам нужно отображать сообщения

  • Если вам требуется пользовательский контент на статической главной странице

  • Отображать связанные, популярные или информационные сообщения

  • Любой другой вторичный или дополнительный контент, выходящий за рамки основного запроса

Когда следует использовать основной запрос.

Для отображения основного содержимого на

  • На вашей домашней странице и странице, установленной в качестве страницы блога в бэкэнде

  • Все страницы архива, которые включают такие шаблоны, как archive.php, category.php, author.php, taxonomy.php, tag.php и date.php

ЧАСТЬ ДВА

Для выбора всех избранных сообщений я использую эту строку, которая создает новый объект WP_Query, определяющий запрос с определенным тегом:

Итак, из того, что я понял, это не основной запрос WordPres, но это новый запрос, созданный мной. Из того, что я понял, лучше создать новый запрос (как сделано) и не использовать основной запрос, когда я хочу выполнять такого рода операции

Правильно. Это выходит за рамки основного запрос. Это вторичный или дополнительный контент, который не может быть создан с помощью основного запроса. Вы ВСЕГДА ДОЛЖНЫ использовать либо WP_Query или get_posts для создания пользовательских запросов.

НИКОГДА НЕ ИСПОЛЬЗУЙТЕ query_posts для создания пользовательских запросов или даже любого другого запроса. Мой акцент.

Примечание: Эта функция не предназначена для использования плагинами или темами. Как будет объяснено позже, существуют лучшие, более эффективные варианты изменения основной запрос. query_posts() - это чрезмерно упрощенный и проблематичный способ изменить основной запрос страницы, заменив его новым экземпляром запроса. Это неэффективно (повторные запуски SQL-запросов) и в некоторых случаях приведет к полному сбою (особенно часто при разбиении сообщений на страницы).

Двигаемся дальше

Хорошо, продолжая, я показываю все сообщения, у которых нет тега featured, для этого я использую этот фрагмент кода, который, наоборот, изменяет основной запрос:

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 чтобы удалить сообщения с тегами избранные с главной страницы

function exclude_featured_tag( $query ) {
    if ( !is_admin() && $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' );

ЧАСТЬ ТРЕТЬЯ

Дополнительные материалы для чтения, которые будут полезны в будущее

 4
Author: Pieter Goosen, 2017-04-13 12:37:28

Создание нового объекта WP_Query() всегда нормально.

$sort= $_GET['sort'];

   if($sort == "pricelow"){
     $sort_args = array('meta_key' => 'price', 'orderby' => 'meta_value_num', 'order', 'ASC');
     $new_query = new WP_Query($sort_args);
    }

    blah blah blah...

Нет, нет, нет, извини за это. Я не видел крючка pre_get_posts.

Код в вашем вопросе хорош для подключения запросов. Как описано в API плагина WordPress/Ссылка на действие/pre_get_posts:

Pre_get_posts запускается до настройки WP_Query.

Таким образом, он подключает WP_Query по умолчанию() там, где вы хотите (в вашем коде он изменяет WP_Query при получении запрос).

В файлах шаблонов используйте новый WP_Query ($args).

 1
Author: mht, 2014-08-30 23:04:33