WordPressではpost_idをパーマリンクの中に入れておくと、移転時にpost_idがずれたときにパーマリンクが切れてしまうという問題があるらしいです。idがずれるとか、そんなバカな話があるか!とも思いますが、致し方ないので対応策を考えてみました。

結論から言うとまだ上手くいっていないのですが、とりあえず何を試してどこで躓いているかを記したいと思います。

まずよく言われるのが、パーマリンクをpost_nameで指定するという方法。でもこれでは記事のタイトルを後で変更したときに、タイトルとスラッグに不一致が出てしまい、個人的に好きじゃありません。一度エントリをあげてからよく手直しをする自分としては嬉しくなく、数字のIDが使いたいのです。そこで他の方法を探してみました。で参考になったのは池田百合子さんによる以下のページへのコメント欄。

「過去記事の post_name として post_id を指定すれば単純に解決」
WordPress のパーマリンク設定を変更 | Numb.

なるほど~。投稿スラッグにpost_idを入れればいいのか!過去記事に対して投稿スラッグにpost_idを指定するバッチ処理をした上で、投稿時に投稿スラッグにpost_idを設定するWordPressのプラグインを作っておくというやり方が良いかもしれないですね。

そこでまずバッチ処理用のコンソールアプリを作成。WordPressのXML-RPC APIを利用して全てのエントリのスラッグをidで上書きします。SQL文でも出来るような気もしますが、せっかく作ったライブラリを使ってみます。

※実行には.Net Framework 3.5 SP1がインストールされている必要があります。

SharpLab.WP-PostSlugRewriter.zip

ソースコード:SharpLab.WP-PostSlugRewriter.sln.zip

実行するに当たっては、前もって必ずBlogのデータのバックアップを取っておいてください。万が一データが破損した場合でも責任は負えません。また、このコンソールアプリでは既に設定されている投稿スラッグも構わず上書きします。あえて残しておきたいスラッグがある場合は(特にページ)、メモしておいて後で直してください。

続いて作りたるは投稿時にスラッグを書き換えるWordPressのプラグイン。フィルタするだけなので簡単お手軽。

中身はこの通り。

<?php
/*
Plugin Name:wp-idslug
Plugin URI:http://www.sharplab.net/
Description:新規エントリの投稿時にエントリのスラッグにidをセットします。
Author:shiroica
Version:1.00
Author URI:http://blog.sharplab.net/
*/

function sharplab_wpidslug_rewriteNewPost($id){



	$currentState = get_post($id);
	if($currentState->post_name != $currentState->ID){
		$post = array();
		$post['ID'] = $currentState->ID;
		$post['post_name'] = $currentState->ID;
		wp_update_post($post);
	}

}

add_filter('save_post','sharplab_wpidslug_rewriteNewPost')

?>

これをWordPressのプラグインフォルダに放り込んでおいた上で、有効化しておきます。これで、全ての記事のスラッグにidが入るようになりました。そこでパーマリンク設定を変更します。

post_idになっているものを

/%category%/%post_id%/

postnameに。

/%category%/%postname%/

postnameにはpost_idが入っているはずなので、これで上手くいくはず…なのですが、なぜか上手くいきません。上手く表示されるページもあるのですが、ページによっては404 Not Foundが返されるのですね。

しかし、年月とpostnameによるパーマリンクでは、(パーマリンクは変わりますが)上手く表示されるという…。

/%year%/%monthnum%/%postname%/

どなたか解決策が分かる方いらっしゃいませんでしょうか…。

Comments :10

らくぶろ 09-04-14 19:03:38 UTC

はじめまして。
ブログ検索から飛んできました。
自分は現在fc2ブログからwordpressに移行途中なのですが、
過去記事はpost_id、これからの記事はpost_nameにしたいとおもっており、自分の目的に当てはまっておりましたのでこちらのバッチファイルを利用しようかとおもっております。
それに関して質問なのですが、こちらのバッチファイルはexeファイルをダブルクリックでよろしいのでしょうか?
こちらの環境(vista)ではエラーがでてしまいコンソールが強制終了してしまいます。(それ以外の方法でしたらちょっとお恥ずかしい限りですが・・)
お忙しい中申し訳ありませんが、ご教示いただけましたら幸いです。

shiroica 09-04-14 20:45:24 UTC

すみません、こちらの説明が足りませんでした。
このコンソールアプリの実行には.Net Framework3.5 SP1が必要です。恐らく、これがインストールされていないのが原因だと思われます。お手数ですが、以下のリンクからDLしてインストールした上で再度試していただけますでしょうか?
http://www.microsoft.com/downloads/details.aspx?familyid=AB99342F-5D1A-413D-8319-81DA479AB0D7&displaylang=ja

らくぶろ 09-04-14 22:47:24 UTC

こんばんわ。
.Net Framework3.5 SP1をダウンロードして実行してみたところ、xmlrpc.phpまでのURL、ユーザー名、パスワードが表示され、それらを記入後に記事一覧の取得を開始しましたと10秒ほど表示された後エラーで強制終了となってしまいます。
もしかすると記事数が膨大(7000記事ほど)なためかもしれません。

また、こちらの環境でもpostnameは年月じゃないと404になりました。参考になれば幸いです。

shiroica 09-04-14 23:26:15 UTC

7000記事ですか…。凄い数ですね。
7000記事を一括DLしようとしてタイムアウトしていると思われるので、とりあえずタイムアウトまでの時間を30分に設定し直したものと差し替えを行いました。新しいプログラムをDLし直したうえで、もう一度試してもらえますでしょうか。

らくぶろ 09-04-14 23:51:13 UTC

夜分にお手数をかけして申しわけございません。
ダウンロードして実行してみたところ、エラーは出なかったのですが「ルート要素が見つかりません」となり停止してしまいました。なおpostnameは変更されておりませんでした・・

shiroica 09-04-15 00:22:12 UTC

とんでもないです。こちらこそ何度もお手数おかけしてすみません。
「ルート要素が見つかりません」というエラーメッセージは、おそらく、一度にDLしようとした記事数が多すぎてWordPressのXML-RPC APIが整形式のXMLを返せなかったためにパースエラーが起きたためだと思います。そこで記事一覧の取得方法を変えてみたものに再度差し替えました。もう一度新しいもので試して頂けますでしょうか?

らくぶろ 09-04-15 00:52:51 UTC

そういっていただけて幸いです。
今回は「ルート表示が複数あります 行2、位置2です」と表示されてしまいました。
何度も申し訳ございませんがよろしくお願いいたします。

shiroica 09-04-15 23:50:37 UTC

返事が遅くなりました。
一万件のエントリを用意して実験してみたところ、こちらの環境でも再現できました。どうも記事を列挙する際にPHPのメモリを使い果たしてしまっているようで、WordPressがエラーを返しているようです。サーバーのphp.iniのmemory_limitを一時的に十分に増やして試してもらえますでしょうか。
権限の関係でphp.iniが弄れない場合は、このコンソールアプリでは対応できなさそうです。申し訳ありません。

らくぶろ 09-04-16 00:19:23 UTC

現在wordpressを設置しているサーバーが共有サーバーですのでphp.iniをいじることは不可能のようでした・・残念です。
こちらの時間が余裕あるときに一旦自宅側のサーバーにて動作テストをし、可能な場合現サーバーにインポートする形をとってみようと思います。
長いあいだお手数おかけしてもうしわけございませんでした。また、ご親切にしていただきありがとうございました。

shiroica 09-04-16 00:28:26 UTC

とんでもないです。こちらこそ力になれず済みません。また何かありましたらお気軽にコメントを残してください。