英文:
Custom page for filtering posts, WordPress is going 404 for any year other than the current year in the URL (&year=)
问题
以下是您提供的代码的翻译:
我有一个名为`news/`的页面。它没有设置为博客页面,我也不想将其设置为博客页面。我只想要几个下拉菜单,配有一个筛选按钮,该按钮将显示符合下拉菜单条件的帖子,并进行分页,否则显示列表中的所有帖子。以下是代码:
// 获取页眉
get_header();
// 获取筛选条件
$category = $_GET['category'] ?? '';
$tag = $_GET['tag'] ?? '';
$year = isset($_GET['year']) ? intval($_GET['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) {
$args['date_query'] = array(
'year' => $year,
);
}
// 创建新的WordPress查询对象
$query = new WP_Query($args);
?>
<?php
// 获取类别、标签和年份的信息
$categories = get_categories(array(
'orderby' => 'name',
'order' => 'ASC'
));
$tags = get_tags(array(
'orderby' => 'name',
'order' => 'ASC'
));
$years = $wpdb->get_col("
SELECT DISTINCT YEAR(post_date)
FROM $wpdb->posts
WHERE post_status = 'publish'
ORDER BY post_date DESC
");
var_dump($years);
var_dump($year);
?>
<!-- 创建筛选表单 -->
<form action="<?php echo esc_url(get_permalink()); ?>" method="get">
<label for="category">选择类别:</label>
<select name="category" id="category">
<option value="">所有文章</option>
<?php foreach ($categories as $category) : ?>
<option value="<?php echo esc_attr($category->slug); ?>" <?php selected(isset($_GET['category']) && $_GET['category'] === $category->slug); ?>>
<?php echo esc_html($category->name); ?>
</option>
<?php endforeach; ?>
</select>
<label for="tag">选择标签:</label>
<select name="tag" id="tag">
<option value="">标签</option>
<?php foreach ($tags as $tag) : ?>
<option value="<?php echo esc_attr($tag->slug); ?>" <?php selected(isset($_GET['tag']) && $_GET['tag'] === $tag->slug); ?>>
<?php echo esc_html($tag->name); ?>
</option>
<?php endforeach; ?>
</select>
<label for="year">选择年份:</label>
<select name="year" id="year">
<option value="">所有年份</option>
<?php foreach ($years as $archive_year) : ?>
<?php var_dump($years); ?>
<option value="<?php echo esc_attr($archive_year); ?>" <?php selected(isset($_GET['year']) && $_GET['year'] === $archive_year); ?>>
<?php echo esc_html($archive_year); ?>
</option>
<?php endforeach; ?>
</select>
<input type="submit" value="筛选">
</form>
<?php if ($query->have_posts()) : while ($query->have_posts()) : $query->the_post(); ?>
<!-- 显示帖子内容 -->
<h2><?php the_title(); ?></h2>
<div class="post-content">
<?php the_content(); ?>
</div>
<?php endwhile; ?>
<!-- 添加分页链接 -->
<?php
global $wp_query;
$total_pages = $wp_query->max_num_pages;
if ($total_pages > 1) {
$current_page = max(1, get_query_var('paged'));
echo '<div class="pagination">';
echo paginate_links(array(
'base' => get_pagenum_link(1) . '%_%',
'format' => 'page/%#%',
'current' => $current_page,
'total' => $total_pages,
'prev_text' => '«',
'next_text' => '»',
));
echo '</div>';
}
?>
<?php else : ?>
<p>没有找到帖子</p>
<?php endif; ?>
<?php wp_reset_postdata(); ?>
<?php
// 获取页脚
get_footer();
这段代码主要用于创建一个自定义的WordPress页面,允许用户根据类别、标签和年份筛选帖子,并分页显示结果。如果您有任何其他问题,请随时提出。
英文:
I have a page I am calling news/
. It is not set as the blog page and nor do I want it to be the blog page. I just want several dropdowns with a filter button that will display posts with a pagination that match the dropdown criteria, otherwise display all posts in the list. Here is the code:
get_header();
$category = $_GET['category'] ?? '';
$tag = $_GET['tag'] ?? '';
$year = isset($_GET['year']) ? intval($_GET['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) {
$args['date_query'] = array(
'year' => $year,
);
}
$query = new WP_Query($args);
?>
<?php
$categories = get_categories(array(
'orderby' => 'name',
'order' => 'ASC'
));
$tags = get_tags(array(
'orderby' => 'name',
'order' => 'ASC'
));
$years = $wpdb->get_col("
SELECT DISTINCT YEAR(post_date)
FROM $wpdb->posts
WHERE post_status = 'publish'
ORDER BY post_date DESC
");
var_dump($years);
var_dump($year);
?>
<form action="<?php echo esc_url(get_permalink()); ?>" method="get">
<label for="category">Select a category:</label>
<select name="category" id="category">
<option value="">All Articles</option>
<?php foreach ($categories as $category) : ?>
<option value="<?php echo esc_attr($category->slug); ?>" <?php selected(isset($_GET['category']) && $_GET['category'] === $category->slug); ?>>
<?php echo esc_html($category->name); ?>
</option>
<?php endforeach; ?>
</select>
<label for="tag">Select a tag:</label>
<select name="tag" id="tag">
<option value="">Tags</option>
<?php foreach ($tags as $tag) : ?>
<option value="<?php echo esc_attr($tag->slug); ?>" <?php selected(isset($_GET['tag']) && $_GET['tag'] === $tag->slug); ?>>
<?php echo esc_html($tag->name); ?>
</option>
<?php endforeach; ?>
</select>
<label for="year">Select a year:</label>
<select name="year" id="year">
<option value="">All Years</option>
<?php foreach ($years as $archive_year) : ?>
<?php var_dump($years); ?>
<option value="<?php echo esc_attr($archive_year); ?>" <?php selected(isset($_GET['year']) && $_GET['year'] === $archive_year); ?>>
<?php echo esc_html($archive_year); ?>
</option>
<?php endforeach; ?>
</select>
<input type="submit" value="Filter">
</form>
<?php if ($query->have_posts()) : while ($query->have_posts()) : $query->the_post(); ?>
<!-- Display your post content here -->
<h2><?php the_title(); ?></h2>
<div class="post-content">
<?php the_content(); ?>
</div>
<?php endwhile; ?>
<!-- Add pagination links -->
<?php
global $wp_query;
$total_pages = $wp_query->max_num_pages;
if ($total_pages > 1) {
$current_page = max(1, get_query_var('paged'));
echo '<div class="pagination">';
echo paginate_links(array(
'base' => get_pagenum_link(1) . '%_%',
'format' => 'page/%#%',
'current' => $current_page,
'total' => $total_pages,
'prev_text' => '&laquo;',
'next_text' => '&raquo;',
));
echo '</div>';
}
?>
<?php else : ?>
<p>No posts found</p>
<?php endif; ?>
<?php wp_reset_postdata(); ?>
<?php
get_footer();
The issue is that for any url, it is working fine as long as the URL is:
https://site/news/?category=&year=2023
Or
https://site/news/?category=&year=
or any URL without the year parameter
The moment you put in:
https://site/news/?category=&year=2022
or any other year, 2022, 2021, 2020 it goes to a 404 page.
If I put a year in via hard code in the above code, but don't have 2022, 2021, 2020 in the url, it will filter fine.
I am assuming this is an issue with the Settings > Permalinks in my WordPress, but I am not understanding how to set it up. Currently it looks like this:
Custom Structure: /%category%/%postname%/
I noticed if I just selected the first option, other years would redirect to the traditional wordpress search and not my custom news/
filter page. I do not want this. I don't care about the traditional WordPress search posts page/functions. I just want all years to filter in place on my custom news page along with the other criteria.
答案1
得分: 1
某些查询字符串参数,包括year
,被WordPress视为“保留”,使用它们可能会引发未定义的行为,包括可能出现404页面。不幸的是,我能找到唯一记录这一情况的位置是在register_taxonomy
页面上,这并不明显,因为这个问题是系统范围的,与分类名称无关。
特别重要的是要避免以下保留术语,如果您通过$_GET或$_POST数组传递术语,这样做可能会导致WordPress以404错误响应,而没有其他提示或解释。
解决这个问题的快速简便方法是选择一个不同的年份参数,例如y
。更长而复杂的解决方案可能是钩入template_include
,但我认为那可能太晚了,查询已经被设置好了,所以您可能需要使用一个专门的重写规则。
如果将来有其他人遇到这个问题,如果您需要年份、月份和日期,并决定使用y
、m
和d
以保持一致性,不幸的是,m
也是保留的,但month
则不是。
英文:
Certain query string parameters, including year
, are considered "reserved" by WordPress, and using them might kick in undefined behavior, including possibly a 404 page. Unfortunately, the only location that I can find that documents this is on the register_taxonomy
page, which is very much not obvious because the problem is system-wide, and not just related to taxonomy names.
> Avoiding the following reserved terms is particularly important if you are passing the term through the $_GET or $_POST array. Doing so can cause WordPress to respond with a 404 error without any other hint or explanation.
The fast and easy solution to this is to just pick a different parameter for the year, such as y
. The longer and more complicated solution is to possibly hook into template_include
, however I think that's too late and the query will already be setup, so instead you might have to have a dedicated rewrite rule instead.
If anyone else stumbles on this some day and you have a need for year, month and day, so you decide to use y
, m
and d
for consistency, unfortunately m
is also reserved, however month
isn't.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论