/home/by-natures/dev*

ソフトウェア開発者として働く人の技術的なメモ

WordPressのパーマリンクを変更したら404エラーになった

WordPressがやけに重いな…と感じていて、さくらのVPSを使っているのでそのせいだろうと対して気にもしていなかったんですが、こちらの記事「WordPressを100倍速くする! MySQLの調整やnginx proxy cache(株式会社クレイ)」を見ると、どうやら仮想環境によらずに大幅に速度改善できる様子。

何事も疑ってみるものだなと、まずは簡単にできそうなWordPressプラグイン「WP Super Cache」を設定しようと思ったら、ちょっとハマッてしまったので記録しておきます。本当はnginxを入れて改善もしようと思ったんですが、パーマリンクと相性が悪いようで、しばらく見送り。なんでもリダイレクトが使えないらしい?(ちゃんと調べないので嘘だったらすみません)。varnishならその辺も行けるので、近々varnishを入れてみるかもしれません。

さて「WP Super Cache」のインストール自体は非常に簡単で、WordPressの管理画面から検索して、インストールするだけです。しかしその後、プラグインの設定画面に

WP Super Cache is disabled. Please go to the plugin admin page to enable caching

と表示されて、WP Super Cacheが使えません。「admin page」をクリックするとパーマリンクの設定画面に飛ぶので、デフォルトのugry パーマリンクだとキャッシュが効かないようです。

WordPressパーマリンクは、デフォルトではugly(?p=Nの形をしたリンク)です。例えば私のブログ記事だと http://bynatures.net/wordpress/?p=1121 のような形になります。しかしGETパラメータで記事IDを指定しているので、WP Super Cacheがこれをキャッシュ出来ないようなんです。そこで今回はパーマリンクを以下のような形に変更しました: http://bynatures.net/wordpress/1121/ 設定は、WordPressの管理画面から「設定」→「パーマリンク設定」→「カスタム構造」で、/%post_id%/とだけ指定しました。

この設定をするとWordPressは気を聴かせて色々変更してくれます。しかしこれだけで済めばいいんですが、問題は記事内で自分で貼ったリンクです。例えば「○○の件については、私が昔書いた記事「XX」をご覧ください」と昔の記事に書いてあったとして、XXに記事のリンクを張っていたとすると、uglyパーマリンクが残ってしまいます。 

結論から言えば、WordPressはこの点も気を聞かせて、.htaccess ファイルを作成してリダイレクトをしてくれます。そして気をつけるべきは、.htaccess を使うので、AllowOverride を Allにする必要があることです:


                Options FollowSymLinks
                AllowOverride All

自分でリダイレクトを書かなきゃいけないんだ、と思い込んでいたので、盲点でした。。このAllowOverride Allさえあれば、パーマリンクを変更してもWordPress.htaccessで上手くやってくれます。

小ネタ:GETパラメータがついたURLのリダイレクト

上の解決法を探る間に、パーマリンク間のリダイレクト設定をしていたので、小ネタを一つ。

GETパラメータがついたURLは、RewriteRuleだけでリダイレクトしようとすると、URIだけしか見てくれないので、パラメータまで扱うことが出来ません。次のようなリダイレクト: http://bynatures.net/wordpress/?p=1121

http://bynatures.net/wordpress/1121/
をしようと思った時に、次のmod_rewriteの設定ではリダイレクトできません:

RewriteRule ^/wordpress/\?p=([0-9]+)$ /wordpress/$1/

上のルールはURIを対象としたものなのですが、実際のパラメータpはGETパラメータとして渡されるので、URIに含まれず、このルールは適用されることがないのです。

GETパラメータも含めて変換したい場合は、次のようなやり方で行えます:

RewriteCond %{QUERY_STRING} p=([0-9]+)
RewriteRule ^/wordpress/$ /wordpress/%1/ [L]

RewriteCond文で変数をキャッチして、変数を使う場合は$ではなく、%を使います。