WordPress.org

Make WordPress Core

Opened 6 years ago

Last modified 4 months ago

#27019 new defect (bug)

Redirect by page slug does not work in permalink structure /%category%/%postname%/

Reported by: dimagsv Owned by:
Milestone: Priority: normal
Severity: normal Version: 3.8.1
Component: Permalinks Keywords: needs-patch bulk-reopened
Focuses: Cc:
PR Number:

Description

Wordpress has a feature to redirect by page slug. For ex. site with two pages:

yoursite.com/pageone/pagetwo

With default permalink settings redirect works like this:

yoursite.com/pagetwo -> yoursite.com/pageone/pagetwo
yoursite.com/randomtext/pagetwo -> yoursite.com/pageone/pagetwo

With permalink structure /%category%/%postname%/ redirection from root stops working:

yoursite.com/pagetwo - 404 error

, but from non root ok:

yoursite.com/randomtext/pagetwo -> yoursite.com/pageone/pagetwo

How to reproduce. Clean wordpress install. Create pages: "pageone", "pagetwo" with parent page "pageone". Try to open url:

yoursite.com/pagetwo - 301 moved

Set custom permalink structure to /%category%/%postname%/. Try to open url:

yoursite.com/pagetwo - 404 error, but 301 expected

I think, permalink structure is for post, not for pages. Am I right?

After investigations I found, "pagetwo" in url "yoursite.com/pagetwo" detected as category name in class-wp.php/parse_request(). And later canonical.php/redirect_guess_404_permalink() does not try to find page by category name, only by get_query_var('name'), that is blank.

Change History (8)

#1 @Latz
6 years ago

Hello dimagsv,

though I don't have a solution I could at least reproduce the error on my system.

#2 in reply to: ↑ description ; follow-up: @mboynes
5 years ago

First off, great research here. You nailed it with your trace: WordPress doesn't try to find pages by category name, only by post name. /%category%/%postname%/ permalink structures fall into a special category called "verbose rewrite rules" where the pages aren't the fallback rules, which is why 'name' isn't set.

Wordpress has a feature to redirect by page slug

Herein lay the problem: It doesn't. The feature is that it tries to guess the permalink of a would-be 404. That's a fallback, like a spare tire, which is nice to have in an unforeseen circumstance but not to be used daily.

In my opinion, this isn't a bug. If you're changing your permalink structure, you should manage your redirects in a more reliable way and not rely upon redirect_guess_404_permalink().

#3 in reply to: ↑ 2 ; follow-up: @dimagsv
5 years ago

Replying to mboynes:

/%category%/%postname%/ permalink structures fall into a special category called "verbose rewrite rules" where the pages aren't the fallback rules, which is why 'name' isn't set.
...
The feature is that it tries to guess the permalink of a would-be 404. That's a fallback, like a spare tire, which is nice to have in an unforeseen circumstance but not to be used daily.

In my opinion, this is a bug in the "fallback". Pages must be the fallback rules in any permalink structure and any url structure.

#4 in reply to: ↑ 3 ; follow-up: @mboynes
5 years ago

Replying to dimagsv:

Pages must be the fallback rules in any permalink structure and any url structure.

That's not possible as things stand, and to make it possible would require WordPress to do a lot more work to display pages.

Rewrite rules are analyzed in sequential order in a loop, and once a path matches a rewrite rule, it exits the loop. However, there's a special condition for verbose rules where it first checks to see if a page exists before exiting the loop. Specifically, when you have a /%category%/%postname%/ structure, the path /foo/bar/ could either be referring to a page bar which has a parent foo, or it could refer to the post bar in the category foo. WordPress accounts for this by checking to see if the page exists, and if not, it assumes that this is a category/post combo. In order for pages to be the fallback rules, WordPress would have to check to see if the category exists, the post exists, and the post is in the category, before it could rule out the category/post rules. While that seems like 3x the effort, it can actually be significantly more, since it might require table joins.

In the end, my contention remains that this is not a bug. If anything, it's a feature request for automatic redirects. If WordPress were to have such a feature, redirect_guess_404_permalink() would not be the way to go; we'd want to instead do something like store the old rules, and process them for 404s. Personally, I wouldn't want such a feature, as it would mean significantly more effort to display 404s, and would make every WordPress site more vulnerable to DOS attacks. I'm sure there are plenty of people who would want that feature, so it's a great idea for a plugin.

#5 in reply to: ↑ 4 ; follow-up: @dimagsv
5 years ago

Replying to mboynes:

If WordPress were to have such a feature, redirect_guess_404_permalink() would not be the way to go; we'd want to instead do something like store the old rules, and process them for 404s. Personally, I wouldn't want such a feature, as it would mean significantly more effort to display 404s, and would make every WordPress site more vulnerable to DOS attacks.

I agree with you. Feature to process the old rules would make WordPress vulnerable. You are right, this must be a plugin.
I propose to create an automatic redirects for pages only. No need to process old rewrite rules. Permalink structure changes very rare. In my case - once at the beginning. But pages moves from root to subpages frequently on site growth. What do you think, should it also be a plugin?

#6 in reply to: ↑ 5 @mboynes
5 years ago

Replying to dimagsv:

What do you think, should it also be a plugin?

Yeah, I think that's a great idea!

#7 @chriscct7
4 years ago

  • Keywords needs-patch added

#10 @skorasaurus
7 months ago

  • Keywords bulk-reopened added

Confirmed that this still exists in WordPress 5.1.1

Note: See TracTickets for help on using tickets.