Make WordPress Core

Opened 4 years ago

#50726 new defect (bug)

Pagination error on 4 digit page when category and year are in the permalink structure

Reported by: elpadi17's profile elpadi17 Owned by:
Milestone: Awaiting Review Priority: normal
Severity: minor Version: 5.5
Component: Rewrite Rules Keywords: needs-patch
Focuses: Cc:


When looking at a category archive page where the page number has four digits, and the permalink structure has the category and year in it, WordPress lumps together the category name and the "page" part of the URL and assumes that the number refers to the year of publication.

Steps to reproduce:

1) Update the permalink structure to /%category%/%year%/%monthnum%/%day%/%postname%/
2) Create a category
3) Create and assign enough posts and/or update posts per page to generate at least 1000 pages.
4) Navigate to page 1000 or greater.

Even though the resulting URL would be /%cat%/page/1000/, WordPress will assume that the category name is "%cat%/page" and that the year of publication is 1,000.

The correct behavior is to go to page 1,000 of the specified category, just as it works in page 999.

This issue leads to 404s being generated by the standard pagination component which get flagged on search engine crawls, resulting in lower search rankings for the entire website.

Here is the immediate fix I added to my website:

 * Allow category pagination with four digits.
 * Because the permalink structure is set as /%category%/%year%/%monthnum%/%day%/%postname%/
 * in the path /investing/page/1000 WordPress thinks:
 *   1) the category name is investing/page
 *   2) 1000 is a year instead of a page number.
add_action('pre_get_posts', function ($query) {
    if (!is_admin()
        && $query->is_main_query()
        && is_archive()
        && substr_count($_SERVER['REQUEST_URI'], '/page/')
    ) {
        $year = $query->query_vars['year'] ?? 0;
        $page = $query->query_vars['paged'] ?? 0;
        if ($year && !$page) {
            $query->set('paged', $year);
        if (isset($query->query['category_name'])) {
            $query->set('category_name', str_replace('/page', '', $query->query['category_name']));

Change History (0)

Note: See TracTickets for help on using tickets.