I have a custom post type called "equipment". I would like the permalink structure to be:


I specifically want it to use a dash and not a slash (i.e. - "id-slug" not "id/slug"). Every possible solution I've found from googling has used slashes and I just can't get it to work with a dash.

I also want to prevent WordPress from adding on the additional number if there's two posts with the same title. Example:


I think the solution is to use add_rewrite_rule, but I'm a bit confused with the regex stuff.

The following code did work to replace the post name with the id in the slug:

function equipment_links($post_link, $post = 0) {
    if($post->post_type === 'equipment') {
        return home_url('equipment/' . $post->ID . '');
        return $post_link;
add_filter('post_type_link', 'equipment_links', 1, 3);

function equipment_rewrites_init(){
    add_rewrite_rule('equipment/([0-9]+)?$', 'index.php?post_type=equipment&p=$matches[1]', 'top');
add_action('init', 'equipment_rewrites_init');

It did return a url of "example.com/equipment/123", but I would like to tack on "-post_name" to the end of that "123".

  • Maybe taking a look here wp_unique_post_slug helps you out, or an example as answer here from Steven Harris.
    – Charles
    Commented Jan 31, 2019 at 17:03

2 Answers 2


I don't have much experience with coding rewrites, but could you just add $post->post_name into your return statement?

return home_url('equipment/' . $post->ID . '-' . $post->post_name );

There are a few other ways to change the permalinks that I have used that may also help you:

  1. The easiest way to change your permalink structure is probably to use a custom structure by going to the admin menu, settings > permalinks. Select custom structure and set it to /%post_id%-%postname%/
  2. If you are looking to edit the permalink structure for the specific post type without touching any code or another post type, I would suggest downloading a plugin like "Custom Post Type Permalinks" or "Simple Post Type Permalinks" both by Toro_Unit.

In regards to the unique identifier, you want to remove at the end.. I don't have that answer. However, if you are willing to use a .htacess rewrite instead of php, you may want to give this a try:



Get the result for permalink structure for your custom post type "equipment" and prevent WordPress from appending a number to the slug if there are posts with the same title, you can use the post_type_link filter hook and customize the permalink generation process.

Add code in your theme functions.php file or in a custom plugin

// Modify the permalink structure for the custom post type "equipment"
function custom_equipment_permalink($permalink, $post) {
    // Make sure it's our custom post type
    if ('equipment' === $post->post_type) {
        // Get the post ID
        $post_id = $post->ID;

        // Get the post name (slug)
        $post_slug = $post->post_name;

        // Construct the permalink with the desired format
        $new_permalink = home_url("/equipment/{$post_id}-{$post_slug}");

        return $new_permalink;

    return $permalink;
add_filter('post_type_link', 'custom_equipment_permalink', 10, 2);

// Prevent WordPress from appending a number to the slug if there are posts with the same title
function prevent_duplicate_post_slugs($slug, $post_ID, $post_status, $post_type) {
    // Make sure it's our custom post type
    if ('equipment' === $post_type) {
        global $wpdb;

        // Get the number of posts with the same slug
        $check_sql = "SELECT post_name FROM $wpdb->posts WHERE post_name = %s AND post_type = %s AND ID != %d LIMIT 1";
        $post_name_check = $wpdb->get_var($wpdb->prepare($check_sql, $slug, $post_type, $post_ID));

        // If there are posts with the same slug, append a number to make it unique
        if ($post_name_check || -1 !== intval(get_page_by_path($slug, OBJECT, $post_type))) {
            $suffix = 2;
            do {
                $alt_post_name = $slug . '-' . $suffix;
                $post_name_check = $wpdb->get_var($wpdb->prepare($check_sql, $alt_post_name, $post_type, $post_ID));
            } while ($post_name_check);

            return $alt_post_name;

    return $slug;
add_filter('wp_unique_post_slug', 'prevent_duplicate_post_slugs', 10, 4);

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.