应该避免 query_posts() 吗? [英] query_posts() should be avoided?

查看:23
本文介绍了应该避免 query_posts() 吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我读到 query_posts() 应该避免使用 wp_query()pre_get_posts().我对弄乱 Loop 没有信心,也不完全理解代码.

I am reading that query_posts() should be avoided in favor of wp_query() and pre_get_posts(). I am not confident with messing with the Loop and do not fully understand the codex.

下面的代码是否使用了 query_posts() ?如果是,并且由于应该避免 query_posts(),您能否提出一种不使用 query_posts() 但仍能完成相同操作的方法?

Does the code below use query_posts() ? If yes and since query_posts() should be avoided, can you suggest a method that does not use query_posts() but still accomplish the same thing?

functions.php 中的这段代码用于按随机或按价格对帖子进行排序.

This code in functions.php is used to sort posts by random or by price.

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(价格)发布在我的菜单中.因此,网站访问者只需单击链接即可对帖子进行排序.

.
Link A (Random) and Link B (Price) are posted in my menu by using this code. Thus the visitor to the website can sort the posts simply by clicking a link.

<a href="http://website.com/?sort=A">Random</a>
<a href="http://website.com/?sort=B">Price</a>

推荐答案

我在 WPSE 上对这个主题做了非常详细的解释,为了它可能对 SO 用户产生的价值和好处,这里是从 WPSE 上的那个问题复制的完整帖子.出于兴趣,这里是 WPSE 上完整帖子的链接:关于主查询和自定义查询如何工作的一些疑问这个自定义主题?

I have done a very detailed explanation on this very topic on WPSE, and for the sake of the value and benefit it might have for SO users, here is the complete post copied from that question on WPSE. For interest sake, here is a link to the complete post on WPSE: Some doubts about how the main query and the custom query works in this custom theme?

您的实际问题基本上是何时运行自定义查询以及何时使用主查询.分成三个部分

Your actual question is basically when to run a custom query and when to make use of the main query. Lets break it down in three parts

第一部分

何时运行自定义查询(这不是一个明确的列表)

When to run a custom query (This is not a definitive list)

  • 创建自定义内容滑块

  • To create custom content sliders

在页面中创建特色内容区域

To create a featured content area in a page

如果您需要显示帖子,请在 page.php 模板上

On page.php templates if you need to display posts

如果您需要在静态首页上自定义内容

If you require custom content on a static front page

显示相关、热门或信息性帖子

Display related, popular or informational posts

主查询范围之外的任何其他次要或补充内容

Any other secondary or supplementary content outside the scope of the main query

何时使用主查询.

显示主要内容

  • 在您的主页和后台设置为博客页面的页面

  • On your homepage and the page set as a blogpage in the backend

所有存档页面,包括 archive.php、category.php、author.php、taxonomy.php、tag.php 和 date.php 等模板

All archive pages which includes templates like archive.php, category.php, author.php, taxonomy.php, tag.php and date.php

第二部分

要选择所有特色帖子,我使用这一行创建一个新的 WP_Query 对象,该对象定义具有特定标签特色的查询:

To select all the featured posts I use this line that create a new WP_Query object that define a query having the specific tag featured:

所以,据我所知,这不是 WordPres 的主要查询,而是我创建的一个新查询.据我所知,最好创建一个新查询(已完成),并且当我想执行此类操作时不要使用主查询

So, from what I have understand, this is not the WordPres main query but it is a new query created by me. From what I have understand it is better create a new query (as done) and not use the main query when I want perform this kind of operations

正确.这超出了主查询的范围.这是无法使用主查询创建的次要或补充内容.您应该总是使用WP_Queryget_posts 创建您的自定义查询.

Correct. This falls out of scope for the main query. This is secondary or supplementary content which cannot be created with the main query. You SHOULD ALWAYS use either WP_Query or get_posts to create your custom queries.

切勿使用 query_posts创建自定义查询,甚至任何其他查询.我的重点.

NEVER USE query_posts to create custom queries, or even any other query. My emphasis.

注意:此功能不适用于插件或主题.正如稍后所解释的,有更好、更高性能的选项来更改主查询.query_posts() 是通过用新的查询实例替换页面的主查询来修改页面主查询的过于简单和有问题的方法.它效率低下(重新运行 SQL 查询)并且在某些情况下会彻底失败(尤其是在处理帖子分页时).

Note: This function isn't meant to be used by plugins or themes. As explained later, there are better, more performant options to alter the main query. query_posts() is overly simplistic and problematic way to modify main query of a page by replacing it with new instance of the query. It is inefficient (re-runs SQL queries) and will outright fail in some circumstances (especially often when dealing with posts pagination).

继续前进

好的,接下来我会显示所有没有特色标签的帖子,为此我使用这个代码片段,相反地修改主查询:

Ok, going on I show all the posts that have not the featured tag, to do this I use this code snippet that on the contrary modify the main query:

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

所以我认为这非常可怕.是真的吗?

So I think that this is pretty horrible. Is it true?

那都是错误的,不幸的是,您的陈述是正确的.如前所述,从不使用query_posts.它运行一个完整的新查询,这对性能不利,并且在大多数情况下会破坏分页,而分页是分页正常工作的主要查询的组成部分.

That is all wrong and your statement is unfortunately true. As said before, NEVER use query_posts. It runs a complete new query, which is bad for performance, and it most cases breaks pagination which is an integral part of the main query for pagination to work correctly.

这是您的主要内容,因此您应该使用带有默认循环的主查询,它应该如下所示,这就是您所需要的

This is your primary content, so you should be using the main query with the default loop, which should look like this, and this is all you need

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

你可以完全摆脱这部分,删除它,烧掉它然后忘记它

You can completely get rid of this part, delete it, burn it and forget about it

<?
// 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, once you've done that, you'll see that posts from the feature tag appear in your home page using the main query and default loop.

从主页删除此标签的正确方法是使用 pre_get_posts.这是更改主查询的正确方法,以及您应该始终用来更改主要内容循环的钩子.

The correct way of removing this tag from the homepage is with pre_get_posts. This is the proper way to alter the main query and the hook you should always use to make changes to your primary content loop.

所以,带有 pre_get_posts 的代码是正确的,这是您应该使用的函数.只是一件事,总是检查你不在管理页面上,因为 pre_get_posts 也会改变后端.所以这是在functions.php中使用的正确代码,用于从主页中删除标记为featured的帖子

So, the code with pre_get_posts is correct and this is the function that you should use. Just one thing, always do a check that you are not on an admin page because pre_get_posts alters the back end as well. So this is the proper code to use in functions.php to remove posts tagged featured from the homepage

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' );

第三部分

额外的阅读材料,对未来有帮助

Extra reading material which will be helpful in future

什么时候应该使用 WP_Query、query_posts() 和 get_posts()?

何时使用 WP_query()、query_posts() 和 pre_get_posts

查询概览

CMS 循环指南

这篇关于应该避免 query_posts() 吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆