最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Regenerate Slugs From Title of Posts

programmeradmin0浏览0评论

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.

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.

Share Improve this question edited Nov 25, 2014 at 15:17 Howdy_McGee 20.9k24 gold badges91 silver badges177 bronze badges asked Mar 19, 2012 at 16:38 Nicola PeluchettiNicola Peluchetti 9641 gold badge8 silver badges17 bronze badges 1
  • 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 Commented Feb 27, 2014 at 3:14
Add a comment  | 

5 Answers 5

Reset to default 28

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.

This plugin also does the job: http://www.jerrytravis/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) {

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.

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.

We had an issue where we migrating and combined a bunch of post types. We had a bunch of blank titles as well. I wrote a WP CLI command to fix them all, but here is the gist of what I did:

    global $wpdb;
    $types = [
      'page',
      // Your CPT machine names
    ];

    // Formats our IN query properly.
    $final = array_map(function($type) {
      return "'" . esc_sql($type) . "'";
    }, $types);

    // Grabs all our empty title fields.
    $query = sprintf("SELECT post_title, ID FROM `%s` WHERE post_type IN (%s) AND post_name = ''",
      $wpdb->posts,
      implode(",", $final)
    );

    foreach ($wpdb->get_results($query) as $post) {
      $title = sanitize_title_with_dashes( $post->post_title );
      $wpdb->update('wp_posts', ['post_name' => $title], ['ID' => $post->ID]);
    }

Needed to do a direct MySQL update since wp_update_post doesn't update the post_name.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论