为什么我的WP_QUERY两次输出我的条目?

时间:2012-10-08 作者:Amit Erandole

我正在使用一个小的快捷码输出一个按几十年排列的电影标题列表。decades 是我的自定义分类法,术语如下1930s 1940s

以下是我的短代码:

[fashionfilms type=fashionfilms  tax=decades]
下面是如何解析该短代码:

add_shortcode(\'fashionfilms\', \'cw_output_fashion_films\');

function cw_output_fashion_films($atts){

    $post_type = $atts[\'type\'];
    $tax = $atts[\'tax\'];
    $tax_terms = get_terms($tax);

    if ($tax_terms) {
      echo "<ul>";
      foreach ($tax_terms  as $tax_term) {
        $args=array(
          \'post_type\' => $post_type,
          "$tax" => $tax_term->slug,
          \'post_status\' => \'publish\',
          \'posts_per_page\' => -1,
          \'ignore_sticky_posts\'=> 1
        );

        $my_query = null;
        $my_query = new WP_Query($args);
        if( $my_query->have_posts() ) {
          echo "<li class=\'letter\'>" . $tax_term->name . "</li>";
          while ($my_query->have_posts()) : $my_query->the_post(); ?>
            <li><a href="<?php the_permalink() ?>" rel="bookmark" title="Permanent Link to <?php the_title_attribute(); ?>"><?php the_title(); ?></a></li>
            <?php
          endwhile;
        }
        wp_reset_query();
      } //end foreach loop
      echo "</ul>";
    }
}
问题是我的条目输出量增加了一倍。

要查看翻倍的内容,请查看我的实时链接here.

以下是我的页面模板代码:

<div class="span9">
            <?php while ( have_posts() ) : the_post(); ?>
            <div <?php post_class(); ?>>
                <h1><?php the_title();?></h1>
                <div class="content">
                    <?php the_content() ?>
                </div>
            </div><!-- /.post_class -->
        <?php endwhile; ?>
        <?php bootstrapwp_content_nav(\'nav-below\');?>

</div><!-- /.span9 -->
我做错了什么?我怎样才能解决这个问题?

4 个回复
最合适的回答,由SO网友:Tom J Nowell 整理而成

你用过wp_reset_query, 但是,您应该使用wp_reset_postdata.

wp_reset_query 获取当前查询对象,并将其替换为主查询。然而,这里的问题是,您使用的是WP\\u Query,它是一个单独的查询对象,主查询没有被触及,不需要保留。

这意味着我们不需要打电话wp_reset_query, 因为查询从未更改。

我们确实打过电话$my_query->the_post 然而这意味着当前帖子数据来自您的自定义查询,需要重置,因此我们调用wp_reset_postdata.

使命感wp_reset_query 当你不需要的时候,可能会产生意想不到的后果,在这种情况下,重复你的帖子

SO网友:Otto

虽然其他答案更具体,但您有一个更紧迫的问题:

Shortcodes should not create output.

我的意思是,您的shortcode处理程序函数永远不应该“回显”任何内容。它应该构建一个字符串并返回它。短代码处理代码将负责将其正确插入内容并为您回显。

如果你自己重复这些东西,那么你的短代码将与很多其他东西不兼容。短代码不仅在输出内容时才被处理,其他代码也可以处理它们。

在短代码(或过滤器)期间进行回音有时会导致输出两次或更多,因为短代码可以在同一页面加载上运行两次(或更多)。

更改函数以返回字符串,而不是回显您试图生成的内容。

更多信息:http://ottopress.com/2011/actions-and-filters-are-not-the-same-thing/

SO网友:Stephen Harris

问题不是wp_reset_query() 它本身。然而,正如@TomJNowell指出的,@hampusn最初建议的那样,您应该使用wp_reset_postdata() 由于您没有更改主查询,因此不需要重置它。

wp\\u reset\\u查询的作用

在呼叫顶部wp_reset_postdata(), wp_reset_query() 只替换主查询$wp_query 具有$wp_the_query (存储的副本)。这两者通过引用链接,因此应该是相同的。。。除非链接断开$wp_query 更改人query_posts() (其中wp_reset_query() 是有意的)。

query_posts() 正在使用query_posts() 更改查询$wp_query 并破坏参考。这就是你循环的内容。让我们假设这个新循环中的第一篇帖子就是使用您的短代码的帖子。在您的呼叫回调中使用wp_reset_query().

$wp_query 现在设置回原始查询-这是我们刚刚打印的帖子的查询。因此,循环基本上重置为原始查询(在本文中,我对问题的评论有点错误*)。此循环打印帖子的内容,并到达末尾。

为什么使用wp_reset_postdata \'解决它

如果使用query_posts() 结果就是你想要的那篇文章——这会导致重复。

为什么不使用wp_reset_postdata \'解决它

如果使用query_posts() 结果包括其他帖子,然后第一次循环将包括这些其他帖子。

解决方案:

简而言之,使用query_posts(). 不要使用它。使用wp_reset_postdata, 虽然在这种情况下正确的做法是掩盖错误。

但我没有使用query_posts()...

我不能确定是否有其他错误会导致您看到的内容。但是在“干净”的安装中,您不应该在上面的代码中看到它(我已经测试过)。

*如果$wp_query$wp_the_query 仍然通过引用链接,那么我的评论实际上是正确的

SO网友:Amit Erandole

根据上面@hampsun的建议,添加wp_reset_postdata() 修复了双输出问题。自定义循环现在显示为:

[...]

function cw_output_fashion_films($atts){

    $post_type = $atts[\'type\'];
    $tax = $atts[\'tax\'];
    $tax_terms = get_terms($tax);

    if ($tax_terms) {
      echo "<ul>";
      foreach ($tax_terms  as $tax_term) {
        $args=array(
          \'post_type\' => $post_type,
          "$tax" => $tax_term->slug,
          \'post_status\' => \'publish\',
          \'posts_per_page\' => -1,
          \'ignore_sticky_posts\'=> 1
        );

        $my_query = null;
        $my_query = new WP_Query($args);
        if( $my_query->have_posts() ) {
          echo "<li class=\'letter\'>" . $tax_term->name . "</li>";
          while ($my_query->have_posts()) : $my_query->the_post(); ?>
            <li><a href="<?php the_permalink() ?>" rel="bookmark" title="Permanent Link to <?php the_title_attribute(); ?>"><?php the_title(); ?></a></li>
            <?php
          endwhile;
        }
        wp_reset_postdata();
      } //end foreach loop
      echo "</ul>";
    }
}
阅读文档后不知道为什么会这样:http://digwp.com/2011/09/3-ways-to-reset-the-wordpress-loop/#wp_reset_postdata

结束

相关推荐

使用新的WP-Query()从循环中过滤后期格式;

嗨,我目前正在为我的博客构建一个主题。下面的代码指向最新的帖子(特色帖子)。因为这将有一个不同的风格比所有其他职位。然而我想过滤掉帖子格式:链接使用我在循环中定义的WP查询,因为它给我带来了更多的灵活性。我该怎么做呢? <?php $featured = new WP_Query(); $featured->query(\'showposts=1\'); ?> <?php while ($featured->have_post