In my plugin, I'm creating a custom post type that has an archive and uses the rewrite parameter to choose a slug:

$args = array (
    'public' => true,
    'has_archive' => true,
    'rewrite' => array('slug' => 'lessons', 'with_front' => false)
register_post_type ('my_plugin_lesson', $args);

With this code, I get an archive of the 'my_plugin_lesson' posts at example.com/lessons/.

However, I can also create a Page with the title "Lessons", and WordPress will assign it the slug 'lessons'. The View Page link on the admin panel for this page will be example.com/lessons/, but the page is inaccessible because WordPress shows the archive for my custom post type.

Is there a way to prevent WordPress from choosing a slug for pages or posts that interfere with the slug of my custom post types?

  • 3
    Take a look at @Rachel Carden's answer to this question: wordpress.stackexchange.com/a/45152/22534 Commented Sep 16, 2013 at 14:41
  • @ialocin Thanks! I guess this is a duplicate. I don't know why I couldn't find that before.
    – Ben Miller
    Commented Sep 16, 2013 at 14:46
  • @G.M. Agreed. Sorry. I've already tried deleting it, but it won't let me delete either.
    – Ben Miller
    Commented Sep 16, 2013 at 15:00
  • I think your apologies is not needed in this case ;)
    – gmazzap
    Commented Sep 16, 2013 at 15:04

2 Answers 2


I know you already find the solution, because you figured out this question was already asked and answered...

However, once this question is a bounty one and cannot be closed as duplicate, I want to make sense to this, and add (a bit of) additional value on the answers already posted.

What is done in those answers (the one by @RachelCarden and the one posted here by @matthew-boynes) is what you need, but it is hardcoded, i.e. you have to manually add the cpt archive slug in the filter function.

What I want to obtain is a filter that works in the same way, but dinamically, something like:

add_filter('wp_unique_post_slug_is_bad_hierarchical_slug', 'prevent_slug_override', 99, 3);
add_filter('wp_unique_post_slug_is_bad_flat_slug', 'prevent_slug_override', 99, 3);

function prevent_slug_override( $now, $slug, $type ) {
  if ( in_array($type, array('nav_menu_item', 'revision', 'attachment') ) )
    return $now;
  $cpts = get_post_types( array('_builtin' => false), 'objects' );
  $check_bad = array();
  foreach ( $cpts as $cpt => $object ) {
    if ( $object->has_archive ) {
      if (
        ! empty($object->rewrite) && isset($object->rewrite['slug']) &&
        ! empty($object->rewrite['slug']) && ($object->rewrite['slug'] != $cpt)
      ) {
        $check_bad[] = $object->rewrite['slug'];
      } else {
        $check_bad[] = is_string($object->has_archive) ? $object->has_archive : $cpt;
  if ( in_array($slug, $check_bad) ) return true;
  return $now;
  • Have you considered submitting a core patch for this? Shouldn't WordPress avoid assigning a slug to a post if it is already in use by a custom post type?
    – Ben Miller
    Commented Sep 17, 2013 at 4:01
  • @BenMiller before submit a core patch it should be tested because there are a lot of configuration possibilities: taking into account configuration in permalink settings and options for register_post_type there are many scenario to consider. Also note that if some custom rewrite rule exists, more variables are added to the problem. Maybe if I have time...
    – gmazzap
    Commented Sep 17, 2013 at 8:25
  • Nice, I like it and will use it in the future - for sure! @BenMiller Good thing you couldn't delete the question :) This is absolutely bounty worthy! Commented Sep 17, 2013 at 10:28

I believe you could leverage the filters in wp_unique_post_slug to prevent this conflict. Try the following

function wpse_109072_is_slug_conflict( $false, $slug, $post_type ) {
    return ( 'page' == $post_type && 'lessons' == $slug );
add_filter( 'wp_unique_post_slug_is_bad_hierarchical_slug', 'wpse_109072_is_slug_conflict', 10, 3 );
add_filter( 'wp_unique_post_slug_is_bad_flat_slug', 'wpse_109072_is_slug_conflict', 10, 3 );

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.