Opened 3 years ago

Last modified 3 months ago

#13459 new defect (bug)

Conflict between post and page slugs/permalinks when permalink setting is set to /%postname%/

Reported by: jamescollins Owned by: ryan
Priority: normal Milestone: 3.6
Component: Permalinks Version: 2.9.2
Severity: normal Keywords: dev-feedback has-patch needs-unit-tests
Cc:

Description

If Dashboard -> Settings -> Permalinks is set to /%postname%/, it is possible to create both a page and a post with the same slug. When viewing via the frontend, the page is always displayed.

I would have thought that WordPress should prevent a post and a page from having the same permalink.

Steps to reproduce:

  1. Create and publish a page with any slug. eg. http://domain.com/test/.
  2. Create and publish a blog post with the same slug. Wordpress says the permalink for the blog post is http://domain.com/test/, but when you visit that URL it displays the page instead.

I can reproduce this on my 2.9.2 install, as well as 3.0 trunk. I'm guessing the bug is present in earlier versions of WordPress as well.

Possibly related: #11863

Attachments (1)

13459.patch (1.2 KB) - added by SergeyBiryukov 4 months ago.

Download all attachments as: .zip

Change History (15)

  • Keywords dev-feedback added

I feel like there is another ticket for this, but can't find it.

In any case, I can't see any easy way to fix this, because pages are allowed to have non-unique slugs across hierarchies. One possibility might be to check for this particular permalink structure and modify the unique slug generation accordingly to ensure that no pages have that slug - but it would only work for new/updated posts - old ones would still have a conflict. Bit flimsy.

comment:2 follow-up: ↓ 5   stephencronin2 years ago

This problem still occurs in 3.1.1.

It persists even after the Page is sent to Trash (the user gets a 404 instead of the Post), until the Page is emptied from the Trash.

The suggestion by solarissmoke is better than nothing. Ideally it would have to work both ways, ie if permalink is /%postname%/ then:

1) check that no posts have this slug when generating top level page slug
2) check that no top level pages have this slug when generating post slug

It may not cover everything:

a) it may not just be posts and pages we have to worry about (some people strip /category/ from URL for category pages for example);
b) there is a very small chance that /%category%/%postname%/ posts could clash with a second level page.

but they are real edge cases and as I said, it's better to do something than nothing.

Related: #16687

#23166 was marked as a duplicate.

comment:5 in reply to: ↑ 2   SergeyBiryukov4 months ago

Replying to stephencronin:

It persists even after the Page is sent to Trash (the user gets a 404 instead of the Post), until the Page is emptied from the Trash.

#21970 would fix that.

#23300 was marked as a duplicate.

Seriously, till now we never fixed this. That's quite a shame.

  • Keywords needs-patch added; dev-feedback removed

#23300 was marked as a duplicate.

  • Keywords dev-feedback added

wp_unique_post_slug() returns a unique slug within the given post type.

Seems like we have 3 options:

  1. Always prevent posts, pages (and CPTs?) from having the same slug (require unique slugs across all post types). Since having the same slug is actually fine with most permalink structures, this sounds like an unnecessary restriction.
  2. Only do the above for the /%postname%/ permalink structure. However, if the structure changes to /%postname%/ later (after the page and the post are created), we'll still end up with a conflict.
  3. Leave this to a plugin, since wp_unique_post_slug() is filterable (#14111).

I personally think that the permalink conflict is to be expected in this case, so the 3rd option sounds acceptable to me.

comment:11 in reply to: ↑ 10   SergeyBiryukov4 months ago

Replying to SergeyBiryukov:

wp_unique_post_slug() returns a unique slug within the given post type.

Correction: As noted in comment:1, pages are allowed to have non-unique slugs across hierarchies:
http://core.trac.wordpress.org/browser/tags/3.5/wp-includes/post.php#L3103

I disagree with leaving this to a plugin. The problem is only for post vs pages when the permalink structure is "/%postname%/".

It seems for me that the 2nd option is the way to go. Obviously changing to the structure will ending up with a conflict but that can be plugin territory.

  • Keywords has-patch added; needs-patch removed
  • Milestone changed from Future Release to 3.6

13459.patch is an attempt to implement option 2.

  • Keywords needs-unit-tests added
Note: See TracTickets for help on using tickets.