Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I'm running a property site where many properties are sold in apartment blocks.

Because of this what the content editors do is create a post/property with all the details and then use a duplicate post plugin to create the others.

Each time they duplicate a post/property they change the title to reflect the property number and maybe change a few bits of meta data E.G price.

What they forget to do is wipe out the slug and let a new one be generated from the title. Here is an example slug from the first property entered:

merle-court-plot-50-182-carlton-vale-nw6-5hh

but then when they duplicate the slugs become:

merle-court-plot-50-182-carlton-vale-nw6-5hh-2
merle-court-plot-50-182-carlton-vale-nw6-5hh-2-2
merle-court-plot-50-182-carlton-vale-nw6-5hh-2-2-2
merle-court-plot-50-182-carlton-vale-nw6-5hh-2-2-2-2
etc

But when they change the titles the slugs would be better like:

merle-court-plot-51-182-carlton-vale-nw6-5hh
merle-court-plot-52-182-carlton-vale-nw6-5hh
merle-court-plot-53-182-carlton-vale-nw6-5hh
merle-court-plot-54-182-carlton-vale-nw6-5hh
etc

So my question:

How do I force the slug to be re-generated on post save, after they have updated the property title?

The slug for this CPT should always be auto generated, there is never a need to manually set it.

share|improve this question

4 Answers 4

up vote 10 down vote accepted

The easiest workaround could be:

function myplugin_update_slug( $data, $postarr ) {
    if ( !in_array( $data['post_status'], array( 'draft', 'pending', 'auto-draft' ) ) ) {
        $data['post_name'] = sanitize_title( $data['post_title'] );
    }
    return $data;
}
add_filter( 'wp_insert_post_data', 'myplugin_update_slug', 99, 2 );
share|improve this answer
    
Does wp_insert_post_data get fired on post update too? The post has already been created by the duplication process. The slug needs changing once the post is updated with the correct title. –  Brady May 22 '12 at 11:01
    
NVM I found the answer to that comment: A filter hook called by the wp_insert_post function prior to inserting into or updating the database. –  Brady May 22 '12 at 11:02
    
Yes, it does. Whenever you create or update a post, this filter will be fired. –  Eugene Manuilov May 22 '12 at 11:14
1  
I've attached to the if statement a check to make sure I'm on my post_type too. –  Brady May 22 '12 at 11:34

Something I've had bookedmarked for a little while is the following (yet untested),

Source LINK

//add our action
add_action( 'save_post', 'my_save_post', 11, 2 );

function my_save_post($post_id, $post){

   //if it is just a revision don't worry about it
   if (wp_is_post_revision($post_id))
      return false;

   //if the post is an auto-draft we don't want to do anything either
   if($post->post_status != 'auto-draft' ){

       // unhook this function so it doesn't loop infinitely
       remove_action('save_post', 'my_save_post' );

      //this is where it happens -- update the post and change the post_name/slug to the post_title
      wp_update_post(array('ID' => $post_id, 'post_name' => str_replace(' ', '-', $_POST['post_title'])));

      //re-hook this function
      add_action('save_post', 'my_save_post' );
   }
}
share|improve this answer
    
In that code surely the re-hook is not needed and even if it was it would need the priority and args set to 11 and 2? Also instead of str_replace() would sanitize_title_with_dashes() be more suitable? –  Brady May 22 '12 at 11:18
    
By calling wp_update_post function, you will call wp_insert_post function, which fires save_post action. You will get infinite loop. –  Eugene Manuilov May 22 '12 at 11:19
    
@EugeneManuilov - but in the code the hook is removed so not to loop infinitely... –  Brady May 22 '12 at 11:24
    
@Brady ah... yes I see. My fault. –  Eugene Manuilov May 22 '12 at 11:29
    
Thanks for the down vote. @Brady I agree that sanitize_title_with_dashes() would be more suitable in that it is a function provided by WP. So wherever possible, swap out regular PHP functionality with WP functions. Although, both would work. As this is not my code, I have not tested it. –  userabuser May 22 '12 at 11:33

Also, run the slug from sanitize_title_with_dashes() through wp_unique_post_slug() to ensure that it's unique. It will automatically append '-2', '-3' etc. if it's needed.

share|improve this answer

Instead of replacing spaces you should use the build in function sanitize_title() which will take care of the replacing for you.

Like this:

sanitize_title($post_title, $post->ID);

Also you should use a unique slug. Which you can get with the function wp_unique_post_slug()

So putting it all together a solution might be:

function myplugin_update_slug( $data, $postarr ) {
  if ( !in_array( $data['post_status'], array( 'draft', 'pending', 'auto-draft' ) ) ) {
    $data['post_name'] = wp_unique_post_slug( sanitize_title( $data['post_title'] ), $postarr['ID'], $data['post_status'], $data['post_type'], $data['post_parent'] );
  }
  return $data;
}
add_filter( 'wp_insert_post_data', 'myplugin_update_slug', 99, 2 );
share|improve this answer
    
Thanks for this! Your change to the accepted answer is very important. It should probably be added to it as an edit though. –  eddiemoya Mar 3 at 6:01

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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