WordPress.org

Make WordPress Core

Opened 5 years ago

Last modified 11 days ago

#13459 assigned defect (bug)

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

Reported by: jamescollins Owned by:
Milestone: Future Release Priority: normal
Severity: normal Version: 2.9.2
Component: Permalinks Keywords: dev-feedback has-patch
Focuses: 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 (6)

13459.patch (1.2 KB) - added by SergeyBiryukov 2 years ago.
13459.2.patch (1.1 KB) - added by moraleida.me 2 years ago.
Exact same patch from SergeyBiryukov, reapplied to current codebase
13459-unit-tests-post.php.patch (1.0 KB) - added by moraleida.me 2 years ago.
post.php.patch (537 bytes) - added by datta.parad 11 months ago.
13459.diff (3.2 KB) - added by MikeHansenMe 4 months ago.
13459-w-test.diff (5.8 KB) - added by MikeHansenMe 4 months ago.

Download all attachments as: .zip

Change History (36)

comment:1 @solarissmoke4 years ago

  • 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: @stephencronin4 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.

comment:4 @SergeyBiryukov2 years ago

#23166 was marked as a duplicate.

comment:5 in reply to: ↑ 2 @SergeyBiryukov2 years 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.

comment:6 @ocean902 years ago

#23300 was marked as a duplicate.

comment:7 @markoheijnen2 years ago

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

comment:8 @ocean902 years ago

  • Keywords needs-patch added; dev-feedback removed

comment:9 @markoheijnen2 years ago

#23300 was marked as a duplicate.

comment:10 follow-up: @SergeyBiryukov2 years ago

  • 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 @SergeyBiryukov2 years 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

comment:12 @markoheijnen2 years ago

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.

@SergeyBiryukov2 years ago

comment:13 @SergeyBiryukov2 years ago

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

13459.patch is an attempt to implement option 2.

comment:14 @SergeyBiryukov2 years ago

  • Keywords needs-unit-tests added

@moraleida.me2 years ago

Exact same patch from SergeyBiryukov, reapplied to current codebase

comment:15 @moraleida.me2 years ago

Simple unit test added to cover the case when the same title is used to create a post and a page AND permalinks are set to /%postname%/

comment:16 @moraleida.me2 years ago

  • Cc moraleida.me added

comment:17 @markjaquith23 months ago

  • Milestone changed from 3.6 to Future Release

Just checking for '/%postname%/' isn't going to cover it completely. Will at least need to standardize trailing slashes on that check. Let's take a look at this early in 3.7.

comment:18 @context19 months ago

  • Cc context added

comment:19 follow-up: @Ipstenu17 months ago

It appears this is no longer restricted to JUST using /%postname%/ as your permalink.

On 3.8 and 3.9-alpha I can make both a page and a post with the same slug. Using /%year%/%postname%/

comment:20 in reply to: ↑ 19 @digiscience15 months ago

For me this is a feature, not a bug. I can place pages into blog lists. Very useful, hope you'll never fix it.

comment:22 @jeremyfelt15 months ago

#27297 was marked as a duplicate.

comment:23 @ryan11 months ago

  • Owner ryan deleted
  • Status changed from new to assigned

comment:24 @SergeyBiryukov11 months ago

#28900 was marked as a duplicate.

@datta.parad11 months ago

comment:25 @datta.parad11 months ago

Actually needs to change parameter of get_post_types function, currently it only return "page" Post type.

comment:26 @SergeyBiryukov10 months ago

#28960 was marked as a duplicate.

@MikeHansenMe4 months ago

comment:27 @MikeHansenMe4 months ago

It also depends which order the page/post is created. So we need to check the permalink structure in both hierarchical and non-hierarchical.

@MikeHansenMe4 months ago

comment:28 @MikeHansenMe4 months ago

  • Keywords needs-unit-tests removed

Added some tests to ensure it is working when different combinations of post/page are made.

comment:29 @SergeyBiryukov2 months ago

#31704 was marked as a duplicate.

comment:30 @SergeyBiryukov11 days ago

#32426 was marked as a duplicate.

Note: See TracTickets for help on using tickets.