15

is it possible to regenerate the slugs programmatically after changing the titles of the post? Numerous post titles were updated and the slug was not updated with the title so I need to regenerate all these slugs.

  • I have had to do this several times and found that between different server environments where it can't handle large arrays ( with numberposts being set to unlimited ) nor calling wp_update_post repeatedly with large memory consumption that breaking it into a WP_Query call with pagination and using $wpdb that it is more manageable and performant. I provided the code sample on a similar post. – codearachnid Feb 27 '14 at 3:14
17

Yes, it is possible.

Sample code, has to be tested and refined:

// get all posts
$posts = get_posts( array (  'numberposts' => -1 ) );

foreach ( $posts as $post )
{
    // check the slug and run an update if necessary 
    $new_slug = sanitize_title( $post->post_title );
    if ( $post->post_name != $new_slug )
    {
        wp_update_post(
            array (
                'ID'        => $post->ID,
                'post_name' => $new_slug
            )
        );
    }
}

I just made this up, there are probably some errors and egde cases, but it should give you an idea. Also, this may take a while, so it could be useful to split the update into smaller chunks.

| improve this answer | |
  • 1
    Hmmm... from my experience, this doesn't work. The post_name argument is ignored by the wp_update_post, at least in the 3.9 version of the core – Alexandre Bourlier Sep 4 '14 at 13:55
  • Currently, post_name is ignored within wp_update_post() function, but it is taken into consideration when the update post calls for the wp_insert_post() function: this means that passing the new slug to the update, will result in effectively changing it for the post being updated. – Erenor Paz May 30 '18 at 8:00
2

This plugin also does the job: http://www.jerrytravis.com/598/wordpress-plugin-to-generate-post-slugs

However, as it only does it for posts which don't have a slug yet, if you need to regenerate slugs edit the following line in the plugin:

if ($post->post_name == "") {

for example, you could change it to:

if (true) {

| improve this answer | |
1

I was trying the method suggested by Toscho, which is the "instinctive one", but in many cases it doesn't work (cf the core code to get what I mean by "many cases").

Looking in the code, I found the wp_insert_post_data filter hook, called by the wp_update_post function right before inserting the post iunto the database.

By calling this filter, and changing the value of $data['post_name'], I was able to get this to work properly. Wordpress is cool but so badly documented...

I edited the documentation, so that more people can find this workaround if needed.

| improve this answer | |
  • Can you point out why wp_update_post overwrites the post_name? the only reason I see for this to happen is if the user trying to modify the post_name is only a contributor (or same level) in which case it shouldn't allow that user to change slug, did you find any other cases in which the post_name is overwritten? – jnhghy - Alexandru Jantea Oct 16 '14 at 7:32
  • Yes this is the proper way to do it. Thank you @Alexandre – user88731 Mar 10 '17 at 8:44
0

you can do this directly in mysql if you need. (our woocommerce site has 100's of thousands of products):

update wp_posts set post_name = concat(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(lower(post_title), '"', ''), "'", ''), ",", '-'), " ", '-'), "&", ''), ";", ''), "@", ''), ".", ''), ":", ''), "/", ''), "+", ''), "(", ''), ")", ''), "--", '-'), "---", '-'), "--", '-'), "--", '-'), '-', id) where post_type = 'product';

where post_type = 'product' - that will keep your update to just woocommerce products; you should figure out what limits you want to keep on this query.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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