Skip to content

Instantly share code, notes, and snippets.

@cdsaenz
Created January 31, 2025 17:30
Show Gist options
  • Save cdsaenz/291d9599e1f20313c3a87edf48233176 to your computer and use it in GitHub Desktop.
Save cdsaenz/291d9599e1f20313c3a87edf48233176 to your computer and use it in GitHub Desktop.
WordPress Remove CPT Base URL and Ensure Unique Slug
<?php
/**
* Add in functions.php or in a specialized plugin
* Change 'location' to the desired CPT which should already exist
* (example created via ACF)
* Mostly extracted from https://wordpress.stackexchange.com/questions/203951/remove-slug-from-custom-post-type-post-urls
* By Matt Keys, arafatgazi and others
*/
// remove post type from permalinks
function remove_post_type( $post_link, $post, $leavename ) {
if ( $post->post_type != 'location' ) {
return $post_link;
} else {
$post_link = str_replace( '/' . $post->post_type . '/', '/', $post_link );
return $post_link;
}
}
add_filter( 'post_type_link', 'remove_post_type', 10, 3 );
// instruct wordpress on how to find posts from the new permalinks
function parse_request_remove_cpt_slug( $query_vars ) {
// return if admin dashboard
if ( is_admin() ) {
return $query_vars;
}
// return if pretty permalink isn't enabled
if ( ! get_option( 'permalink_structure' ) ) {
return $query_vars;
}
$cpt = 'location';
// store post slug value to a variable
if ( isset( $query_vars['pagename'] ) ) {
$slug = $query_vars['pagename'];
} elseif ( isset( $query_vars['name'] ) ) {
$slug = $query_vars['name'];
} else {
global $wp;
$path = $wp->request;
// use url path as slug
if ( $path && strpos( $path, '/' ) === false ) {
$slug = $path;
} else {
$slug = false;
}
}
if ( $slug ) {
$post_match = get_page_by_path( $slug, 'OBJECT', $cpt );
if ( ! is_admin() && $post_match ) {
// remove any 404 not found error element from the query_vars array because a post match already exists in cpt
if ( isset( $query_vars['error'] ) && $query_vars['error'] == 404 ) {
unset( $query_vars['error'] );
}
// remove unnecessary elements from the original query_vars array
unset( $query_vars['pagename'] );
// add necessary elements in the the query_vars array
$query_vars['post_type'] = $cpt;
$query_vars['name'] = $slug;
$query_vars[$cpt] = $slug; // this constructs the "cpt=>post_slug" element
}
}
return $query_vars;
}
add_filter( 'request', "parse_request_remove_cpt_slug" , 1, 1 );
// avoid creating posts, pages or CPT (ie location) with existing slugs.
function prevent_slug_duplicates( $slug, $post_ID, $post_status, $post_type, $post_parent, $original_slug ) {
$check_post_types = array(
'post',
'page',
'location'
);
// If not one of the types we care about, just return the slug
if ( ! in_array( $post_type, $check_post_types ) ) {
return $slug;
}
// Check for duplicate slug in relevant post types
$suffix = 1;
$original_slug = $slug;
// Loop until we find a unique slug
while ( true ) {
if ( 'location' == $post_type ) {
// Check for existing post or page with the same slug
$post_match = get_page_by_path( $slug, 'OBJECT', 'post' );
$page_match = get_page_by_path( $slug, 'OBJECT', 'page' );
if ( $post_match || $page_match ) {
$slug = $original_slug . '-' . $suffix;
$suffix++;
} else {
break; // Slug is unique, exit loop
}
} else {
// Check if location already exists with the same slug for a post or page
$custom_post_type_match = get_page_by_path( $slug, 'OBJECT', 'location' );
if ( $custom_post_type_match ) {
$slug = $original_slug . '-' . $suffix;
$suffix++;
} else {
break; // Slug is unique, exit loop
}
}
}
return $slug;
}
add_filter( 'wp_unique_post_slug', 'prevent_slug_duplicates', 10, 6 );
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment