自定义WordPress新闻筛选页非当前年份参数触发404求助
问题原因
WordPress默认将year作为核心查询变量,当自定义页面传入year参数时,WP会自动尝试匹配年份归档页面的重写规则,再加上你的固定链接结构/%category%/%postname%/,会让WP误判请求路径,最终触发404。另外原代码的分页逻辑依赖全局$wp_query而非自定义查询,也会导致分页异常。
解决方案
1. 注册自定义查询变量
在主题的functions.php中添加代码,告诉WP我们的year、category、tag是自定义参数,不要触发默认归档规则:
function register_custom_query_vars( $vars ) { $vars[] = 'year'; $vars[] = 'category'; $vars[] = 'tag'; return $vars; } add_filter( 'query_vars', 'register_custom_query_vars' );
2. 修改自定义页面模板代码
调整参数处理、查询逻辑和分页部分,修复类型匹配和分页依赖问题:
<?php get_header(); // 获取并安全处理筛选参数,统一类型避免匹配错误 $category = isset($_GET['category']) ? sanitize_text_field($_GET['category']) : ''; $tag = isset($_GET['tag']) ? sanitize_text_field($_GET['tag']) : ''; $year = isset($_GET['year']) ? sanitize_text_field($_GET['year']) : ''; $year_int = $year ? intval($year) : 0; $paged = (get_query_var('paged')) ? get_query_var('paged') : 1; $args = array( 'post_type' => 'post', 'orderby' => 'date', 'order' => 'DESC', 'posts_per_page' => 10, 'paged' => $paged, 'category_name' => $category ?: '', 'tag' => $tag ?: '', ); if ($year_int) { $args['date_query'] = array( 'year' => $year_int, ); } // 初始化自定义查询 $query = new WP_Query($args); // 获取分类、标签、年份选项 $categories = get_categories(array( 'orderby' => 'name', 'order' => 'ASC' )); $tags = get_tags(array( 'orderby' => 'name', 'order' => 'ASC' )); global $wpdb; $years = $wpdb->get_col(" SELECT DISTINCT YEAR(post_date) FROM $wpdb->posts WHERE post_status = 'publish' AND post_type = 'post' ORDER BY post_date DESC "); ?> <form action="<?php echo esc_url(get_permalink()); ?>" method="get"> <label for="category">选择分类:</label> <select name="category" id="category"> <option value="" <?php selected($category, ''); ?>>全部文章</option> <?php foreach ($categories as $cat) : ?> <option value="<?php echo esc_attr($cat->slug); ?>" <?php selected($category, $cat->slug); ?>> <?php echo esc_html($cat->name); ?> </option> <?php endforeach; ?> </select> <label for="tag">选择标签:</label> <select name="tag" id="tag"> <option value="" <?php selected($tag, ''); ?>>全部标签</option> <?php foreach ($tags as $t) : ?> <option value="<?php echo esc_attr($t->slug); ?>" <?php selected($tag, $t->slug); ?>> <?php echo esc_html($t->name); ?> </option> <?php endforeach; ?> </select> <label for="year">选择年份:</label> <select name="year" id="year"> <option value="" <?php selected($year, ''); ?>>全部年份</option> <?php foreach ($years as $archive_year) : ?> <option value="<?php echo esc_attr($archive_year); ?>" <?php selected($year, (string)$archive_year); ?>> <?php echo esc_html($archive_year); ?> </option> <?php endforeach; ?> </select> <input type="submit" value="筛选"> </form> <?php if ($query->have_posts()) : ?> <?php while ($query->have_posts()) : $query->the_post(); ?> <h2><?php the_title(); ?></h2> <div class="post-content"> <?php the_content(); ?> </div> <?php endwhile; ?> <!-- 修复分页逻辑:使用自定义$query,同时保留所有筛选参数 --> <?php if ($query->max_num_pages > 1) : ?> <div class="pagination"> <?php echo paginate_links(array( 'base' => add_query_arg(array('category' => $category, 'tag' => $tag, 'year' => $year)) . '%_%', 'format' => 'page/%#%', 'current' => max(1, $paged), 'total' => $query->max_num_pages, 'prev_text' => '«', 'next_text' => '»', )); ?> </div> <?php endif; ?> <?php else : ?> <p>暂无文章</p> <?php endif; ?> <?php wp_reset_postdata(); ?> <?php get_footer(); ?>
3. 刷新固定链接设置
进入WP后台 → 设置 → 固定链接,无需修改任何设置,直接点击「保存更改」,让WP重新生成重写规则,确保自定义查询变量生效。
关键修改说明
- 注册查询变量:避免WP将
year等参数识别为核心归档变量,防止误触发404 - 参数类型统一:将
year参数转为字符串后再和下拉选项值比较,修复selected函数的匹配问题 - 分页逻辑修复:使用自定义查询
$query的分页数据,同时在分页链接中保留所有筛选参数,保证分页后筛选条件不丢失 - 年份查询优化:在获取年份列表的SQL中增加
post_type = 'post',避免获取到其他自定义文章类型的年份
内容的提问来源于stack exchange,提问作者JoeD
相关产品推荐
相关产品推荐

