在对随机帖子进行分页时重复发帖

时间:2014-12-13 作者:Lucas Santos

我有1个定制的Post类型的产品以及typescountries. 我正在我的taxonomy.php 分页分页的页面。

我还使用自定义帖子类型和自定义字段插件来帮助存储产品的数据,如“名称”和“图像”。

这就是我在分类法中的做法。php:

<div class="container">

<?php

//first get the current term
$current_term = get_term_by( \'slug\', get_query_var( \'term\' ), get_query_var( \'taxonomy\' ) );


  $args = array(
    \'post_type\'      => array( \'products\' ),
    \'orderby\' => \'rand\',
    \'post_per_page\' => \'10\',
    \'tax_query\' => array(
    array(
      \'taxonomy\' => $current_term->taxonomy,
      \'field\'    => \'slug\',
      \'terms\'    => $current_term,
    ),
    ),
    \'paged\' => ( get_query_var( \'paged\' ) ) ? get_query_var( \'paged\' ) : 1 );

  $products_query = new WP_Query( $args );

  $temp = $wp_query; 
  $wp_query = null; 
  $wp_query = $products_query; 

  while ($products_query->have_posts()) : $products_query->the_post(); 
?>

<!--product image and title-->
<div>
  <a href="<?php the_permalink(); ?>"><img src="<?php the_field(\'image\'); ?>" alt="Name of Product"></a>
</div><!--product-image-->

<div>
<?php the_field(\'title\'); ?>
</div><!--title end-->

<?php endwhile; ?>


<?php 

//getting paginations in numbers
global $wp_query;

$total_pages = $wp_query->max_num_pages;

if ($total_pages > 1){

  $current_page = max(1, get_query_var(\'paged\'));

  echo paginate_links(array(
      \'base\' => get_pagenum_link(1) . \'%_%\',
      \'format\' => \'/page/%#%\',
      \'current\' => $current_page,
      \'total\' => $total_pages,
      \'before_page_number\' => \'<div class="pagination-navigation">\',
      \'after_page_number\' => \'</div>\'

    ));
}
?>

<?php 
  $wp_query = null; 
  $wp_query = $temp;  // Reset
?>
<?php wp_reset_postdata(); ?>
</div><!--container end-->
因此,我不得不将主查询更改为该查询,因为我的分页工作不正常,每次尝试转到下一页时都会出现404错误。不管怎样,直到昨天,我才发现我的产品在我进入下一页时都会重复它们自己。

示例:

第一页有5辆车

Car1

汽车2

汽车3

车辆4

车辆5

然后,当我转到下一页时,它将显示下一系列的产品剪辑,但至少有1或2个会像这样重复主题本身。

Car6

车辆7

Car2(已显示在第1页)

汽车8

车辆9

我真的不明白它为什么这么做。此外,在我的管理区域阅读>设置我有blog pages show at most set to 10 以防万一。

有什么建议吗?

UPDATE

因此,添加

session_start();

add_filter(\'posts_orderby\', function ($orderby_statement) {

    $seed = $_SESSION[\'seed\'];
    if (empty($seed)) {
      $seed = rand();
      $_SESSION[\'seed\'] = $seed;
    }

    $orderby_statement = \'RAND(\'.$seed.\')\';
    return $orderby_statement;
});
我的职能。php确实可以工作,但我的所有项目都不会随机生成。每次我转到第1页时,无论我刷新页面多少次,都会出现相同的产品。

所以我的功能。php看起来是这样的。

add_action( \'pre_get_posts\', function ( $q ) {
    if( !is_admin() && $q->is_main_query() && $q->is_tax() ) {
        $q->set( \'posts_per_page\', 2 );
        $q->set( \'orderby\', \'rand\' );
    }
});


//

session_start();

add_filter(\'posts_orderby\', function ($orderby_statement) {

    $seed = $_SESSION[\'seed\'];
    if (empty($seed)) {
      $seed = rand();
      $_SESSION[\'seed\'] = $seed;
    }

    $orderby_statement = \'RAND(\'.$seed.\')\';
    return $orderby_statement;
});
现在,我尝试了更新的代码,并将函数更改为如下所示:

session_start();

add_filter(\'posts_orderby\', \'edit_posts_orderby\');

function edit_posts_orderby($orderby_statement) {

    $seed = $_SESSION[\'seed\'];
    if (empty($seed)) {
      $seed = rand();
      $_SESSION[\'seed\'] = $seed;
    }

    $orderby_statement = \'RAND(\'.$seed.\')\';
    return $orderby_statement;
}

add_action( \'pre_get_posts\', function ( $q ) {
    if( !is_admin() && $q->is_main_query() && $q->is_tax() ) {
        $q->set( \'posts_per_page\', 2 );
        $q->set( \'orderby\', \'rand\' );
    }
});

remove_filter(\'posts_orderby\', \'edit_posts_orderby\');
现在它将随机生成,但返回到重复项目

2 个回复
SO网友:Pieter Goosen

老实说,我真的认为你所有的痛苦都是由分页功能造成的,正如我们刚才简要讨论的那样。

您确实有几个问题是导致您遇到问题的原因

无论出于何种原因,将主查询更改为自定义查询几乎总是一件令人头痛的事,应该始终避免。主查询可以通过pre_get_posts 满足您的需求。我已经做了a post 刚才关于这个完整的问题,你可以去读一下

取消主查询与使用query_posts, 你永远不应该使用它。这可能是分页彻底失败的主要原因之一

Note: 此功能不适用于插件或主题。如后文所述,有更好、性能更好的选项来更改主查询。query\\u posts()是一种过于简单且有问题的方法,通过将页面的主查询替换为新的查询实例来修改它。它效率低下(重新运行SQL查询),并且在某些情况下会彻底失败(尤其是在处理POST分页时)。

我认为调试这个问题并继续前进的最简单方法是去掉自定义查询。复制此代码并将其粘贴到分类中。php文件。

<div class="container">

<?php 
while( have_posts() ) { 
    the_post(); 
?>

    <!--product image and title-->
    <div>
      <a href="<?php the_permalink(); ?>"><img src="<?php the_field(\'image\'); ?>" alt="Name of Product"></a>
    </div><!--product-image-->

    <div>
    <?php the_field(\'title\'); ?>
    </div><!--title end-->

<?php } ?>


<?php 

//getting paginations in numbers
global $wp_query;

$total_pages = $wp_query->max_num_pages;

  $current_page = max(1, get_query_var(\'paged\'));

  echo paginate_links(array(
      \'base\' => get_pagenum_link(1) . \'%_%\',
      \'format\' => \'/page/%#%\',
      \'current\' => $current_page,
      \'total\' => $total_pages,
      \'before_page_number\' => \'<div class="pagination-navigation">\',
      \'after_page_number\' => \'</div>\'

    ));
?>

</div><!--container end-->
你现在至少应该得到正确的帖子,按照发布日期的顺序。首先,确保其工作正常。如果分页不起作用,请不要担心,正如我所说的,我知道您的函数有问题

您现在可以使用pre_get_posts 更改帖子顺序并添加自定义posts_per_page

在函数中粘贴以下内容。php

add_action( \'pre_get_posts\', function ( $q ) {
    if( !is_admin() && $q->is_main_query() && $q->is_tax() ) {
        $q->set( \'posts_per_page\', 10 );
        $q->set( \'orderby\', \'rand\' );
    }
});
默认情况下,分类法页面上应包含帖子类型,因此无需将其添加到pre_get_posts 行动

这将为您提供模板的正确输出。正如我所说的,确保这是有效的,如果分页不起作用,现在不要担心这一点,首先获得应该得到的输出。

如果除了分页之外,所有功能都正常工作,则需要查看分页函数。进行所有这些更改后,如果分页不起作用,请告诉我

编辑1我搜索了一些可能的解决方案,找到了this article written by Hugh Lashbrooke

问题

当您导航到结果的第二页时,这些帖子会再次随机返回,您会得到一组完全不同的帖子,其中可能包含也可能不包含您已经查看过的帖子

解决方案。。。我们将使用MySQL’s RAND() 函数,并为其提供种子值,以便在每次后续页面加载时使用相同的随机顺序。为此,我们将随机字符串存储为PHP会话变量,以便MySQL可以使用它作为每个页面使用顺序的参考。

请注意,关于代码,您将在该代码段的第7行注意到一个额外的操作–每次加载文章的第一页时,我们都会重置种子值。这意味着,只要有人停留在分页页面上,他们就会看到一组一致的结果,但一旦他们回到第一页,随机性就会重置,他们会以完全不同的顺序看到帖子。

session_start();

add_filter( \'posts_orderby\', \'randomise_with_pagination\' );
function randomise_with_pagination( $orderby ) {

    if( is_tax() ) {

        // Reset seed on load of initial archive page
        if( ! get_query_var( \'paged\' ) || get_query_var( \'paged\' ) == 0 || get_query_var( \'paged\' ) == 1 ) {
            if( isset( $_SESSION[\'seed\'] ) ) {
                unset( $_SESSION[\'seed\'] );
            }
        }

        // Get seed from session variable if it exists
        $seed = false;
        if( isset( $_SESSION[\'seed\'] ) ) {
            $seed = $_SESSION[\'seed\'];
        }

            // Set new seed if none exists
            if ( ! $seed ) {
                $seed = rand();
                $_SESSION[\'seed\'] = $seed;
            }

            // Update ORDER BY clause to use seed
            $orderby = \'RAND(\' . $seed . \')\';
    }

    return $orderby;
}
编辑2这段代码工作得很好,我现在已经一遍又一遍地测试了它。如果这对您不起作用,您必须重新检查代码。你必须注意以下几点。

给定的代码only 以分类法归档页为目标,这就是is_tax() 使用条件标记。如果您需要在任何其他模板上使用该标记,则需要修改/更改该条件标记

贴子不重复,贴子only 重置当访问第一篇帖子时,其他页面不受影响。确保未缓存您的结果。

作为最后一次尝试,以下是only 您应该从函数中的此答案获得的代码。php

add_action( \'pre_get_posts\', function ( $q ) {
    if( !is_admin() && $q->is_main_query() && $q->is_tax() ) {
        $q->set( \'posts_per_page\', 10 );
        $q->set( \'orderby\', \'rand\' );
    }
});
session_start();

add_filter( \'posts_orderby\', \'randomise_with_pagination\' );
function randomise_with_pagination( $orderby ) {

    if( is_tax() ) {

        // Reset seed on load of initial archive page
        if( ! get_query_var( \'paged\' ) || get_query_var( \'paged\' ) == 0 || get_query_var( \'paged\' ) == 1 ) {
            if( isset( $_SESSION[\'seed\'] ) ) {
                unset( $_SESSION[\'seed\'] );
            }
        }

        // Get seed from session variable if it exists
        $seed = false;
        if( isset( $_SESSION[\'seed\'] ) ) {
            $seed = $_SESSION[\'seed\'];
        }

            // Set new seed if none exists
            if ( ! $seed ) {
                $seed = rand();
                $_SESSION[\'seed\'] = $seed;
            }

            // Update ORDER BY clause to use seed
            $orderby = \'RAND(\' . $seed . \')\';
    }

    return $orderby;
}

SO网友:Mark Kaplun

在随机查询中,您将获得两个不同绘图之间的重复项。由于每次抽签都是独立的随机抽签,因此分页没有多大意义。

如果您将随机种子设置为常量,那么它就不再是随机的,您可以进行分页。将种子存储在cookie中意味着对于不同的用户存在随机性,但对于第一次查看页面后的同一用户则不存在随机性。您可能希望缩短cookie的到期时间,但之后您将再次运行,可能会出现重复的情况。

。。。。。一旦站点上线,您就可以添加一些缓存插件,比如W3TC,并且每小时只有一次随机性(基于您的缓存设置)。

我看不到你的随机性+分页问题的解决方案,你必须放松其中一个。一种可能是将种子保持在一个瞬间,并每分钟更改一次,您将得到重复的种子,但可能不太明显。

结束

相关推荐

Pagination and Related Posts

是否可以对嵌入在single中的以下相关POST代码使用分页。我的主题的php。 <?php // for use in the loop, list 5 post titles related to first tag on current post $tags = wp_get_post_tags($post->ID); if ($tags) { $first_tag = $