#18962 closed defect (bug) (fixed)
Allow duplicate slugs for different content
Reported by: | maorb | Owned by: | wonderboymusic |
---|---|---|---|
Milestone: | 4.1 | Priority: | normal |
Severity: | major | Version: | 2.9 |
Component: | Permalinks | Keywords: | has-patch has-unit-tests |
Focuses: | Cc: |
Description
Currently, the slug of a post (or any other CPT) must be unique.
If a content is being created and an already existing slug is being assigned to it - WP will add a number for identification (i.e. about-2 etc).
That means, that if one has content from different content types, or in different categories (taxonomies), it still cannot have same slug.
The issue might be very disturbing when working in a multi lingual site (i.e using WPML or any other plugin for that).
Suppose there is an about page - www.mysite.com/about.
This is in the main language of the site.
Than a translation to that content page is being added, let's say it is translation to English.
You would expect url something like www.mysite.com/en/about, but the slug is being changed to about-2, so the url of the about page in English becomes www.mysite.com/en/about-2.
For a site with 10 languages, let's say, it will end with urls like site.com/lang/about-10 etc.. and this is not looking good and may confuse.
As a cms, WP should let the admin/developer/operator - to have same slugs for different content types, or even in the same content type. The $post->ID is the unique identifier of a content, why should be also the slug?
Attachments (5)
Change History (56)
#4
@
13 years ago
You can use the same slug in multiple hierarchical post types, but only for a page that is NOT top-level, AND NOT the same level w/in the same post type.
The function wp_unique_post_slug() disallows identical slugs for the same post_parent. and since all top-level pages of heirarchical pages have a [post_parent] => 0, they can't have the same slug.
Not sure if that's intentional, but it is the result. Been testing it lately, here's the URLs possible:
/test/
/test/test/
/test/test-2/
/test/test/test/
/cpt-name/test-2/
/cpt-name/test-2/test/
All the above "test" slugs have a different [post_parent], so the identical slug is allowed. All the above "test-2" slugs had the same parent as another "test" slug, so the "-2" was added.
In the case of "/cpt-name/test-2/" the post_parent was 0, same as "/test/", so its slug got a "-2."
#6
@
12 years ago
- Keywords needs-unit-tests added
I would love to fix this. To do so, we will need some unit tests.
#9
@
12 years ago
Many of the top Content Management Systems allow the same slug to be used across many different parents. An example of a website that has good information architecture is http://www.riverisland.com.
Considering WordPress has moved away from being a simple blogging tool and into the realm of a powerful CMS, shouldn't we remove the need for sibling slugs to be unique?
#10
@
12 years ago
- Milestone changed from Awaiting Review to Future Release
Yes, we should, but it's easier said than done. WP would have to look at the permalink structure to check if the final URL would be ambiguous or not.
#11
follow-up:
↓ 12
@
12 years ago
More tests:
I have IA as such at the moment:
/test1/subtest1/ (works perfectly) /test2/subtest1/ (works perfectly) /test2/subtest2/ (works perfectly)
When I try to navigate to
/test1/subtest2/
, which does not exist, instead of getting a 404 (which I am expecting), I am instead redirected to
/test2/subtest2/
, which, from an IA point of view, detrimental. Also, testing needed if normally I would not have access to /test2/subtest2/
, after the redirect, will I get a restricted page, or bypass security and view the contents?
#13
follow-up:
↓ 14
@
12 years ago
- Cc mboynes@… added
Can someone please explain why wp_unique_post_slug
works the way it does with regards to hierarchical custom post types versus non-hierarchical custom post types?
That is, if two custom post types have 'hierarchical'
set to false
, posts can share the same slug. However, if two custom post types have it set to true
, they cannot. This can be seen in http://core.trac.wordpress.org/browser/trunk/wp-includes/post.php#L3036 where the hierarchical post types check:
SELECT post_name FROM $wpdb->posts WHERE post_name = %s AND post_type IN ( '" . implode( "', '", esc_sql( $hierarchical_post_types ) ) . "' ) ...
(where $hierarchical_post_types
is an array of all hierarchical post types). By comparison, non-hierarchical post types check:
SELECT post_name FROM $wpdb->posts WHERE post_name = %s AND post_type = %s ...
(where post_type's %s
is merely the current post's post type).
I'm sure that I'm missing something, but when I modify this to restrict the hierarchical post types query to just the current post type, everything appears to work just fine. Patch forthcoming.
@
12 years ago
Modifying wp_unique_post_slug to allow posts in hierarchical post types to share slugs with posts in other hierarchical post types
#14
in reply to:
↑ 13
;
follow-up:
↓ 32
@
12 years ago
Replying to mboynes:
Can someone please explain why
wp_unique_post_slug
works the way it does with regards to hierarchical custom post types versus non-hierarchical custom post types?
Introduced in [11125] as a fix for page/attachment slug conflicts in #6437.
[21845] (#15665) was a more recent fix. Perhaps [11125] can be reverted now.
#21
@
11 years ago
- Keywords has-patch needs-testing added
- Milestone changed from 3.9 to Awaiting Review
Appears to still need unit tests.
#22
@
11 years ago
- Milestone changed from Awaiting Review to Future Release
We definitely want to fix this, so moving to Future.
#24
follow-ups:
↓ 25
↓ 26
@
11 years ago
Looks like I never posted it on this ticket; here's a plugin which allows duplicate slugs across post types.
#25
in reply to:
↑ 24
@
11 years ago
Replying to johnbillion:
Looks like I never posted it on this ticket; here's a plugin which allows duplicate slugs across post types.
plugin doesnt work for me. wont leyt me do>>
CPT1/slug1
CPT2/slug1
not sure if plugin is meant to do that ?
#26
in reply to:
↑ 24
@
10 years ago
Replying to johnbillion:
Looks like I never posted it on this ticket; here's a plugin which allows duplicate slugs across post types.
The plugin only seems to allow you to specify duplicate slugs, but if you have the following permalink structure you only seem to be able to view one post (I presume it's the post with the highest/lowest ID)
/%category%/%postname%/
A site I've recently migrated has multiple posts that have the same slug, but they are all within separate categories so I originally assumed it would be ok.
Is there a way to get this to work? Maybe a hook into the 'template_redirect' action or something?
#27
@
10 years ago
The problem:
- Add new media called "banana.jpg", the slug is "banana".
- Add new post with the tag "banana".
- Add "banana" to the "fruit" Custom Post Type.
The result:
The media has a slug called "banana".
The tag has the slug "banana-2".
The fruit Custom Post Type has a slug of "banana-3".
I've read other feedback which says that "Link categories", posts and pages can all conflict too...
What we need to know is: Does the patch resolve this?
#28
@
10 years ago
- Keywords needs-unit-tests removed
- Severity changed from normal to major
- Type changed from enhancement to defect (bug)
- Version set to trunk
Upgrading this to a bug.
As per post.php:
Page slugs must be unique within their own trees. Pages are in a separate namespace than posts so page slugs are allowed to overlap post slugs.
It's fair to say that media, tags, custom post types, link categories, posts and pages are different "trees".
I've upgraded this to 'major' severity due to the effect it can have on URL structure, which could potentially have a detrimental effect to a site if a slug points to the wrong place.
I've explored the 'tests' looking for the word 'slug', yet this yields no results, therefore the lack of unit test is not one created by this issue and therefore should not be addressed by this issue.
#29
@
10 years ago
I tested the 'Allow Duplicate Slugs' plugin by 'John Blackbourn', however, this did not seem to allow duplicate slugs. John suggests it has stopped working since v3.9, but he's yet to explore the problem.
I also tested the 'wp-includes_post.diff' patch to v3.9.1, this did not allow duplicate slugs either. Using the 'quick edit' of my custom taxonomy, it gave the error: The slug “banana” is already in use by another term.
I also tested the patch by 'jfarthing84' instead on v3.9.1, this also did not allow the slug to be changed.
This does seem to be a common problem.
A quick search in Google for "slug" "is already in use by another term" "wordpress" renders about 389,000 results.
#31
@
10 years ago
FWIW, just applied the patch to 4.0-src, and everything works as expected. Within the same post type, hierarchical or not, I cannot have duplicate slugs. Across post types, hierarchical or not, I can have duplicate slugs. This seems to have always been possible with non-hierarchical post types, but not with hierarchical.
Also, I've noted that the ability to create taxonomy terms of the same name, across hierarchical custom taxonomies, seems to be possible as of this patch.
I'm surely missing something, but this definitely seems to be an improvement. Happy to dig into unit tests for this - if anyone has pointers for what specific assertions we should be testing for, I'm all ears - otherwise, I'll just give it a go.
#32
in reply to:
↑ 14
@
10 years ago
- Component changed from Rewrite Rules to Permalinks
- Keywords commit has-unit-tests added; needs-testing removed
- Milestone changed from Future Release to 4.1
Replying to SergeyBiryukov:
Replying to mboynes:
Can someone please explain why
wp_unique_post_slug
works the way it does with regards to hierarchical custom post types versus non-hierarchical custom post types?
Introduced in [11125] as a fix for page/attachment slug conflicts in #6437.
[21845] (#15665) was a more recent fix. Perhaps [11125] can be reverted now.
I've traced this same history and I concur with this finding. It should never have been turned into what it is now.
I'm going to upload a new patch with some basic tests. If someone wants to expand on this, that's fine. Honestly, the only way this can go wrong if two post types share the same rewrite base, and or have their rewrite base removed, and that's going to have problems at the rewrite level, not just this level.
#33
@
10 years ago
What about custom taxonomies?
Why I cannot set the same slug for category and tag?
#34
@
10 years ago
- Owner set to wonderboymusic
- Resolution set to fixed
- Status changed from new to closed
In 30158:
#40
follow-up:
↓ 45
@
10 years ago
- Resolution fixed deleted
- Status changed from closed to reopened
@wonderboymusic - How does this change handle attachments?
Attachments need to be unique across all post types (I'm not entirely sure why, but that's what the code says), take this scenario:
- Create a page /test/
- Upload a file which ends up at /test/example/
- Create a page /test/example/
Previously creating the page would be blocked and created as /test/example-2, but it looks like this now allows that, and as a result the post_type check should be changed to post_type IN( $post_type, 'attachment')
?
Re-opening pending that and #30339
#41
@
10 years ago
Added a unit test which shows the scenario, and the potential fix. This also includes the change for #30339 and a unit test for it.
#42
@
10 years ago
The test_get_page_by_path_priority()
unit test gets broken by these new tests. Now fixing it, then this will go in.
#43
@
10 years ago
Actually, test_get_page_by_path_priority()
is broken by the addition of attachment
to the query clause in 18962.2.diff.
I'm going to leave that out for beta 2 and circle back to it.
#45
in reply to:
↑ 40
@
10 years ago
Replying to dd32:
@wonderboymusic - How does this change handle attachments?
Attachments need to be unique across all post types (I'm not entirely sure why, but that's what the code says), take this scenario:
- Create a page /test/
- Upload a file which ends up at /test/example/
- Create a page /test/example/
Previously creating the page would be blocked and created as /test/example-2, but it looks like this now allows that, and as a result the post_type check should be changed to
post_type IN( $post_type, 'attachment')
?
Re-opening pending that and #30339
I can't reproduce this previous behavior. On 4.0, reating that page /test/example/ will successfully create a page with the slug 'example', creating a URL clash with the attachment. The changes in [21845] mean that the page always wins, so that the attachment page is inaccessible. (See #15665.) And, in fact, if what dd32 is saying here were true, I'm not sure how test_get_page_by_path_priority()
ever would have passed.
My interpretation is: [21845] didn't really fix the problem. It put the fix in the URL parser (get_page_by_path()
) when it should have prevented the duplicate slug to begin with. dd32's suggestion with 18962.2.diff seems like it's the correct fix for the current ticket, and it also seems like a partial fix for #15665. (The "proper" fix for the latter ticket would probably be more specific: when creating an attachment, check that the parent post doesn't have a child with the same slug, and vice versa.)
#46
@
10 years ago
I can't reproduce this previous behavior.
Neither can I now, although I did test it on an actual installation. So you're right, that's not a regression from 4.0.
It does however seem like a edgecase that should be considered, creating a page that conflicts with a existing image attachment at that url level seems wrong. Especially considering that attachments uploaded after the page is created will avoid that clash.
#47
@
10 years ago
- Keywords commit removed
It does however seem like a edgecase that should be considered, creating a page that conflicts with a existing image attachment at that url level seems wrong. Especially considering that attachments uploaded after the page is created will avoid that clash.
Agreed. 18962.patch is my suggested fix. It implements dd32's suggestion that wp_unique_post_slug()
check attachments as well as the same post_type for post_name clashes. As noted, this breaks test_get_page_by_path_priority()
, because in the process of setting up fixtures, you can no longer natively create a page and attachment with the 'some-page' slug. So I suggest directly updating the DB in order to replicate the (legacy) situation where you have an attachment/page conflict, so that the get_page_by_path()
fix continues to be tested.
This ticket was mentioned in Slack in #core by clorith. View the logs.
9 years ago
#50
follow-up:
↓ 51
@
9 years ago
Hi,
More problems with this...
Fist, you need the permanlinks set to /%postname%/.
Then, you can add a new page with the title Slug Test, the permanlink will be slug-test
(added by WordPress) after that, add a new post with the Title Slug Test
, and WordPress will add the same permanlink slug-test
Both permanlinks are created by WordPress, but only one works because only one slug-test
can exist. http://example.com/slug-test/
This is a very big problem...
#51
in reply to:
↑ 50
@
7 years ago
Replying to j.conti:
Hi,
More problems with this...
Fist, you need the permanlinks set to /%postname%/.
Then, you can add a new page with the title Slug Test, the permanlink will be
slug-test
(added by WordPress) after that, add a new post with the TitleSlug Test
, and WordPress will add the same permanlinkslug-test
Both permanlinks are created by WordPress, but only one works because only one
slug-test
can exist.http://example.com/slug-test/
This is a very big problem...
That is true and that covered under a different ticket - #13459
I think this ticket fixed the ability to have the same slug as long as they were on different hierarchal levels (I am not sure, please correct if I'm wrong).
(i.e. domain.com/category/bananas and domain.com/bananas)
Hmm, I thought you could have the same slug across multiple post types, but I've just tested it and evidently you can't. Maybe this is a regression?
The only case where you can have the same slug for multiple posts is on different levels within hierarchical post types. Eg. example.com/hello and example.com/sub-page/hello. If this is allowed then it's odd that the same slug isn't allowed across post types.
I've built a plugin for WPML which allows duplicate slugs for the same content across languages. If you're interested email me at my username at gmail and I'll send it over.
And just to address your core point, slugs have to remain unique within their post type for obvious reasons, so they are uniquely identifiable at their URL.