英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论