WordPress.org

Make WordPress Core

Opened 5 years ago

Last modified 2 months 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 3 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 13 months ago.
13459.diff (3.2 KB) - added by MikeHansenMe 6 months ago.
13459-w-test.diff (5.8 KB) - added by MikeHansenMe 6 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 @SergeyBiryukov3 years ago

#23166 was marked as a duplicate.

comment:5 in reply to: ↑ 2 @SergeyBiryukov3 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 @ocean903 years ago

#23300 was marked as a duplicate.

comment:7 @markoheijnen3 years ago

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

comment:8 @ocean903 years ago

  • Keywords needs-patch added; dev-feedback removed

comment:9 @markoheijnen3 years ago

#23300 was marked as a duplicate.

comment:10 follow-up: @SergeyBiryukov3 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 @SergeyBiryukov3 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 @markoheijnen3 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.

@SergeyBiryukov3 years ago

comment:13 @SergeyBiryukov3 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 @markjaquith2 years 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 @context21 months ago

  • Cc context added

comment:19 follow-up: @Ipstenu19 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 @digiscience17 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 @jeremyfelt17 months ago

#27297 was marked as a duplicate.

comment:23 @ryan13 months ago

  • Owner ryan deleted
  • Status changed from new to assigned

comment:24 @SergeyBiryukov13 months ago

#28900 was marked as a duplicate.

@datta.parad13 months ago

comment:25 @datta.parad13 months ago

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

comment:26 @SergeyBiryukov13 months ago

#28960 was marked as a duplicate.

@MikeHansenMe6 months ago

comment:27 @MikeHansenMe6 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.

@MikeHansenMe6 months ago

comment:28 @MikeHansenMe6 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 @SergeyBiryukov4 months ago

#31704 was marked as a duplicate.

comment:30 @SergeyBiryukov2 months ago

#32426 was marked as a duplicate.

Note: See TracTickets for help on using tickets.