如何让next_posts_link()仅展示用户未评分的WordPress投稿?
解决WP_Query结合wp-postratings实现未评分帖子分页的问题
你的问题核心在于分页逻辑是基于所有已发布帖子,而非用户未评分的帖子——原代码先查询所有帖子,再在循环里跳过已评分的,但next_posts_link()只认最初WP_Query的分页参数,导致点击下一页时可能加载到已评分帖子,最终显示空白。
要解决这个问题,我们需要把「排除已评分帖子」的逻辑提前到WP_Query查询阶段,让分页直接基于用户未评分的帖子总数。具体步骤如下:
1. 利用wp-postratings的数据库表过滤帖子
wp-postratings会把用户的评分记录存在wp_ratings_users表(表前缀根据你的配置可能不同),我们可以通过SQL联表查询,直接排除当前用户已评分的帖子。
2. 修改后的完整代码
<?php $current_user_id = get_current_user_id(); // 定义过滤器:联表并排除已评分帖子 function exclude_rated_posts_join($join) { global $wpdb, $current_user_id; // 仅对登录用户生效 if ($current_user_id > 0) { $join .= " LEFT JOIN {$wpdb->prefix}ratings_users ru ON {$wpdb->prefix}posts.ID = ru.post_id AND ru.user_id = {$current_user_id}"; } return $join; } function exclude_rated_posts_where($where) { global $wpdb, $current_user_id; if ($current_user_id > 0) { $where .= " AND ru.post_id IS NULL"; } return $where; } // 添加过滤器 add_filter('posts_join', 'exclude_rated_posts_join'); add_filter('posts_where', 'exclude_rated_posts_where'); // 执行WP_Query,注意添加paged参数 $paged = get_query_var('paged') ? get_query_var('paged') : 1; $my_query = new WP_Query(array( 'posts_per_page' => 1, 'orderby' => 'rand', 'post_status' => 'publish', 'paged' => $paged, )); // 循环显示帖子 if ($my_query->have_posts()) : while ($my_query->have_posts()) : $my_query->the_post(); // 这里直接展示帖子详情即可,无需再判断是否已评分 the_title('<h2>', '</h2>'); the_content(); // 显示评分组件 if (function_exists('the_ratings')) { the_ratings(); } endwhile; // 翻页按钮,使用查询的最大页数 next_posts_link('Next →', $my_query->max_num_pages); // 移除过滤器,避免影响其他查询 remove_filter('posts_join', 'exclude_rated_posts_join'); remove_filter('posts_where', 'exclude_rated_posts_where'); wp_reset_postdata(); else : echo '没有未评分的帖子了!'; endif; ?>
关键说明
- 过滤器的作用:通过
posts_join联表ratings_users,posts_where排除存在当前用户评分记录的帖子,确保WP_Query返回的都是未评分内容。 - 分页参数:添加
paged参数让WP_Query正确处理分页,next_posts_link使用$my_query->max_num_pages确保翻页按钮只在有未评分帖子时显示。 - 未登录用户处理:如果用户未登录,过滤器不会生效,会显示所有已发布帖子(你可以根据需求调整这部分逻辑)。
关于orderby rand的注意事项
使用随机排序时,每次刷新页面可能会出现重复的帖子(因为随机顺序会重新生成)。如果需要固定的随机分页顺序,可以先获取所有未评分帖子的ID,存储到用户session中,再分页读取这个列表。示例思路:
// 仅在第一次访问时生成随机ID列表 if (!isset($_SESSION['unrated_post_ids'])) { $unrated_ids = get_posts(array( 'post_status' => 'publish', 'fields' => 'ids', // 这里复用之前的过滤器逻辑排除已评分帖子 )); shuffle($unrated_ids); $_SESSION['unrated_post_ids'] = $unrated_ids; } // 从session中读取当前页的ID $current_ids = array_slice($_SESSION['unrated_post_ids'], ($paged-1)*1, 1); $my_query = new WP_Query(array( 'post__in' => $current_ids, 'post_status' => 'publish', ));
这样就能保证分页顺序是固定的随机序列,不会重复或跳过帖子。
内容的提问来源于stack exchange,提问作者Stitchy
相关产品推荐
相关产品推荐

