WordPressでパーマリンクを乱数にする

最近は、個別URLをIDやスラッグじゃなくて、乱数にするのが流行りのようで。
たしかに、タイトルは変わることがあるし、IDよりもURLに統一感があっていい。

あと、URLをIDで直打ちとかされないのも結構いいかも。

ということで、WordPressでパーマリンクを設定していきます。

方針

  • リビジョンは停止
  • wp-postsテーブルのpost_nameに乱数を保存
  • 乱数は20桁
  • 「新規投稿を追加(DB上ではauto-draft)」のステータスでなくなったら、post_nameに個別乱数を保存
    つまり、新規投稿時点ではpost_nameは空になる
  • フックポイント「wp_insert_post_data」で処理する
  • なので、自動保存でも乱数がpost_nameに保存される

こんな感じでいきます。

wp-config.phpでリビジョンを停止する

乱数にするにあたって、最近のWordPressの記事投稿のデータ遷移(リビジョン、下書き、parentなど)を追いかけてやるとテストが面倒なので、リビジョンはとりあえず廃止。

リビジョンは便利だけど、DBが重くなるし(全部wp-postに保存してるので)、無駄なデータは持っていても仕方がないので、停止します。

define('WP_POST_REVISIONS', false);
##ここよりも上に書く
require_once(ABSPATH . 'wp-settings.php');

テーマのfunction.phpにフックを追加

元ネタはこちら

元ネタの通りだと、ページをリロードする度に乱数が生成され、その時の乱数がGUIDに入る仕様。それだと、複数ユーザーで書き込んだ時に、乱数が被る可能性があるので、「新規投稿が保存された(公開を含む)」段階で、乱数を確定するようにしました。

使っているテーマのfunction.phpの一番下に入れれば、基本OKです。
function.phpを自身で修正している場合は、フックポイント「wp_insert_post_data」の段階で、$data[“post_name”]の中身が変わるようになれば大丈夫かと思います。

/**
  post_nameをランダム文字列に
**/
add_filter( 'wp_insert_post_data', 'unique_rand_post_name', 10, 3);

function unique_rand_post_name($data, $postarr) {
    if($data["post_name"] === ""){
        $data["post_name"] = so_11762070_unique_post_slug('post_name');
    }
    return $data;
}

# From: https://stackoverflow.com/a/11762698
function so_11762070_unique_post_slug($col, $table='wp_posts'){
     global $wpdb;

     $alphabet = array_merge( range(0, 9), range('a','z') );

     $already_exists = true;
     do {

         $post_name_chr = array();
         for ($i=0; $i<32; $i++)
         $post_name_chr[] = $alphabet[array_rand( $alphabet )];

         //文字列の桁数
         $digit = 20;
         $post_name = sprintf( "%s", implode("", array_slice($post_name_chr, 0, $digit, true)) );


       // check that post_name is unique
       $already_exists = (boolean) $wpdb->get_var("
       SELECT COUNT($col) as the_amount FROM $table WHERE $col = &#039;$post_name&#039;
       ");    
      } while (true == $already_exists);

     return $post_name;
}

こんな感じです。