I'm trying to make a custom permalink structure for my posts.

www.example.com / post / %post_id% / %posttitle% /

In this permalink, the post's ID comes first, then the post's title after it.

Things I know until now

postname is usually stored in the wp_posts table in the post_name row, and it controlles the post's URL. ie: if the post's post_name is my-post-name, it's default URL will be www.example.com/post/my-post-name.

post names are stored in the database in a way such that every post has a unique post name. If two posts have the same title (for example new-advanced-topic), the first post's name will be new-advanced-topic and the second post's name will be new-advanced-topic-2. And so there URLs will differ from each other.

What I want

But I don't want the post's URL to depend on the post's name stored in the database.

The structure I want is similar to

www.example.com / post / %post_id% / %posttitle% /

Suppose that There is 2 posts stored in the database with these values

║ ID ║     post_title     ║      post_name      ║
║ 25 ║ new-advanced-topic ║ new-advanced-topic  ║
║ 26 ║ new-advanced-topic ║ new-advanced-topic2 ║
  • I want the post's URL to depend only on the post's ID. So if the user requested www.example.com/post/25/pla-pla-pla, The post that will be displayed is the one which it's id is 25.
  • When a user requests the link www.example.com/post/{%post_id%}/pla-pla-pla, I want WordPress to redirect him to www.example.com/post/{%post_id%}/{%post_title%}.

So if user requested www.example.com/post/25/pla-pla-pla, WordPress will redirect him to www.example.com/post/25/new-advanced-topic and display the post with ID=25.

And if user requested www.example.com/post/26/new-advanced-topic2, WordPress will redirect him to www.example.com/post/26/new-advanced-topic and display the post with ID=26.

And if user requested www.example.com/post/100/new-advanced-topic, a 404 error should appear to him since there's no post stored in the database with ID=100.

I tried to write a new rewrite_rule to do this but I couldn't figer any way to write it's regex.

How can I do this using the wp_rewrite rules.

  • I haven't even thought this through properly but I can promise you that you are up for a world of pain with that as soon as you e.g. use plugins.
    – kraftner
    Feb 8, 2016 at 16:30
  • 1
    The part of requesting post/25/anything-here and serve the post with ID 25 and redirecting to correct URL, is the easy part. Having two same slugs I think is more difficult. Currently WordPress allows same slugs for diffrent content types but not for the same content type. Think about it, it is really a very bad approach. It is bad to have two same titles, even worst if they share the slug. I can not think in any valid use case or any good reason to do it. Why do you want to do such thing?.
    – cybmeta
    Feb 8, 2016 at 20:10

2 Answers 2


We have to do this keeping post_name unique. Otherwise, it might cause many troubles. We can use post_title with sanitize_title. In this way, you can keep your URL nice and clean, and your post_name will remain unique as well.

First we will need to write custom permalink structure.

function my_awesome_permalink( $url, $post, $leavename ) {
    $url= trailingslashit( home_url('/post/'. $post->ID .'/'. sanitize_title($post->post_title) .'/' ) );
    return $url;
add_filter( 'post_link', 'my_awesome_permalink', 10, 3 );

Now, our custom permalink structure is ready. It will become www.example.com/post/{%post_id%}/{%post_title%} e.g.: www.example.com/post/25/my-awesome-post-title . We will need to add proper rewrite rule to make WP understand and return the right post.

add_action('generate_rewrite_rules', 'custom_rewrite_rules');
function custom_rewrite_rules( $wp_rewrite ) {
    $new_rules['^post/([0-9]+)/([^/]+)/?'] = 'index.php?p=$matches[1]';
    $wp_rewrite->rules = $new_rules + $wp_rewrite->rules;
    return $wp_rewrite;

With above code, you will be able to make your post permalink structure to www.example.com/post/25/my-awesome-post-title and it will show correct post.

One problem with above code is, you won't be able to edit post slug from post editor. But your post url now comes from post title, which is editable!

  • 2
    @birgire thanks for pointing it out. I actually copied it from my functions.php and forgot to remove that part. Edited now. Feb 10, 2016 at 14:33
  • It didn't work :( . I added it to the functions.php file and it didn't work. I tried also to add flush_rewrite_rules(); and nothing changed.
    – Abozanona
    Feb 10, 2016 at 17:12
  • 1
    @YazanWYusuf did you put these codes properly? I have tested, and working. However, you will need to resave permalink from Settings > Permalink. It will flush rewrite rules. And you should avoid using flush_rewrite_rules(), unless extensively necessary. Feb 10, 2016 at 23:56

What I understand that you want to use post ID instead of Post Title .

and you have trouble because of the same titles name .

If that's right , the solution will be like following :

1 - change permalink to custom structure like the following figure

enter image description here

2- go to phpmyadmin and change your posts name like following figure

enter image description here

  • if that is not the answer just tell me more Feb 3, 2016 at 3:36
  • I want both of the post ID and Post Title to appear in the URL. But choosing the right post to display should depend only on the post ID. The Post's title has no affect in displaying posts. Beside that, I don't want to change the database every time someone adds a new post. I want to do this using rewrite_mod so it's applied on all posts.
    – Abozanona
    Feb 3, 2016 at 4:03
  • 1
    there are many problem may appear to you , if you use the same post titles [ SEO ], look to this article wpbeginner.com/plugins/… Feb 3, 2016 at 4:25

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.