ホーム > タグ > Wordpress
Wordpress
WordPressのURLをhackする
- 2009年7月5日 4:07 PM
- 未分類
hackする、ってほどのことではないんですが、ようやく構造がわかってきたので。メモをかねて。
このブログでは、Wordpressを http://penguinlab.jp/blog にインストールし、記事単一のページのURLを http://penguinlab.jp/blog/post/(一意の記事番号、記事スラッグを利用) にするため、管理ページの「設定」-「パーマリンク設定」で、パーマリンクを post/%postname% とした。
さらに同じ設定ページでカテゴリベースとタグベースを設定した(/blog/category/(カテゴリ名) および /blog/tag/(タグ名) とした)のだが、日付別表示に関してはベースURLの設定がなく、/blog/post/2009/4 のようになってしまう。/blog/postは単一記事専用としたいので、ここは /blog/date/2009/4 のようなかたちにしたいところだ。
いろいろ調べてもいい方法がなさそうだったので、結局プラグインを作ることになった。
WordPressがURLを解決する仕組み
まずはWordpressがインストールされているディレクトリにある.htaccessを見てみよう。
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /blog/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /blog/index.php [L]
</IfModule>
# END WordPress
細かいところは違うだろうが、だいたいこのかたちになっているはずだ。5,6行目の「RewriteCond %{REQUEST_FILENAME} !-f 」「RewriteCond %{REQUEST_FILENAME} !-d 」は、リクエストされたファイル/ディレクトリがなければ、7行目の書き換えルールを適用するという意味だ。7行目は全部index.phpにアクセスさせるということを意味する。つまり、リクエストされたとこにファイルかディレクトリがればそれを返し、なければWordpressの index.phpに丸投げしている。
で、index.phpでは、リクエストされたURLを解析してindex.phpにパラメータを付けたかたちに書き換える。たとえば /blog/2009/4は/blog/index.php?year=2009&month=4 のように書き換えられ、投稿日が2009年4月の記事が表示される。試してみるとわかるが、この整形後のURLをブラウザのアドレスバー/ロケーションバーに直接入力してもアクセスできる。
URL書き換えルール
で、じゃあそのURL書き換えルール(Rewrite Rules)をどうやって設定してるかというと、(wordpressのインストールディレクトリ)/wp-include/rewrite.phpでそのルールを作っているらしい。Wordpressの管理者ページの「設定」-「パーマリンク設定」で「変更を保存」した際などにこのルールを作り直してるものと思われる。
で、いま、その整形のルールがどんな風になっているかは Internal Rewrite Viewer というプラグインを導入することでみることができる(インストール→有効化→「設定」-「パーマリンク設定」-「変更を保存」→(ブログURL)/rewritesでアクセスできる)。以下は今回の変更を加える前のURL書き換えルールの抜粋である。
Array
(
[post/([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})/?$] => index.php?year=$1&monthnum=$2&day=$3
[post/([0-9]{4})/([0-9]{1,2})/?$] => index.php?year=$1&monthnum=$2
[post/([0-9]{4})/?$] => index.php?year=$1
)
URL書き換えルールは連想配列で、キーが表向きのURL、値がindex.phpにパラメータが付いたかたちで定義されているのがわかる。 さてこれをどのように弄ればいいだろうか。
フィルターでURL書き換えルールを書き換える
WordPressはプラグインを使うために、フィルターという仕組みを用意している。
WordPressのソースをみると、プラグインで処理を挟みたいような部分で、apply_filtersという関数が呼ばれている。これは、プラグインがadd_filterという関数で登録した関数を呼び出してくれるものだ。
で、URL書き換えルールを作る部分にもフィルターが設定できる。今回は日付別一覧を弄りたいので、date_rewrite_rulesにフィルターを設定する(「プラグイン API/フィルターフック一覧 – WordPress Codex 日本語版」にURL書き換えのフィルターフック一覧がある)。
フィルター追加のひな形はこんな感じである。
function my_filter($arg){
$result = "";
return $result;
}
add_filter('date_rewrite_rules', 'my_filter');
呼び出される関数にどんな引数が渡されるかは、フィルターフックによって変わる。どんなものが渡されるかについてはあんまり情報がないので、場合によってはWordpressのソースからapply_filter呼び出してるとこを探すことになる。
date_rewrite_rulesの場合、上でInternal Rewrite Rulesプラグインで見たような、連想配列のかたちで渡される。
あとはフィルター内で好きなように書き換えて返してやればよい。今回は最初のpost/部分をdate/に書き換える。
function add_date_base($rewrite_rules){
$r = array();
while(list ($key, $val) = each($rewrite_rules)) {
$r[str_replace('post/', 'date/', $key)] = $val;
}
return $r;
}
add_filter('date_rewrite_rules', 'add_date_base');
テンプレートで書き出されるリンク先の変更
これで、思い通りのURLでアクセスする方法はわかったが、まだ1つ問題がある。テンプレートで書き出されるリンクが変更前のままなのである。これもまたフィルターを設定することで解決できる。
プラグイン API/フィルターフック一覧 – WordPress Codex 日本語版にリンク関連のフィルターフック一覧がある。これらのフィルターフックは引数として、URL文字列を渡してくる(http://penguinlab.jp/blog/date/2009 のような、プロトコル名から始まる完全なかたちのURLである)。単なる文字列なので、文字列関数で適当に書き換えて返してやればOKだ。なお、日付別表示のリンクは年別、年月別、年月日別の3種あるので、すべて書き換える。
function add_date_base_link($string){
$string = str_replace('post/', 'date/', $string);
return $string;
}
add_filter('year_link', 'add_date_base_link');
add_filter('month_link', 'add_date_base_link');
add_filter('day_link', 'add_date_base_link');
あとはこれをプラグインにするだけだ。
プラグインの作成、有効化、URL書き換えルールの再作成
WordPressプラグインの作成方法は他所にいくらでも書かれていると思うので、簡単な説明にとどめておく。
まず、さきほど書いたコードにタイトルなどのメタデータを書き加え、適当な名前で(ローカルに)保存しておく。
<?php
/*
Plugin Name: Add Date Base
Description: Add date base
Version: 1.0
Author: labocho
*/
function add_date_base($rewrite_rules){
$r = array();
while(list ($key, $val) = each($rewrite_rules)) {
$r[str_replace('post/', 'date/', $key)] = $val;
}
return $r;
}
function add_date_base_link($string){
$string = str_replace('post/', 'date/', $string);
return $string;
}
add_filter('year_link', 'add_date_base_link');
add_filter('month_link', 'add_date_base_link');
add_filter('day_link', 'add_date_base_link');
add_filter('date_rewrite_rules', 'add_date_base');
?>
さらに適当な名前のディレクトリを作成し、この中にさきほど保存したファイルを移動しておく。
次に、これを (WordPressのインストールディレクトリ)/wp-content/plugins の下にディレクトリごとコピーする(あるいはディレクトリごとzipにして、管理ページからアップロードしてもよい)。
あとはWordpressの管理ページを開き「プラグイン」-「インストール済み」にさきほど作成したプラグインが表示されているので、有効化する。
無事、有効化できたら、URL書き換えルールを再作成するために、管理者ページから、「設定」-「パーマリンク設定」-「変更を保存」をクリックする。うまくいっていればこれで作業は完了である。思い通りのURLでアクセス出来るか、確認する。うまくいかない場合は、いや、うまくいった場合でもInternal Rewrite RulesでどのようにURL書き換えルールが変化したか確認しよう。
今回の変更では、上に挙げた部分が以下のように変わっていることを確認した。
Array
(
[date/([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})/?$] => index.php?year=$1&monthnum=$2&day=$3
[date/([0-9]{4})/([0-9]{1,2})/?$] => index.php?year=$1&monthnum=$2
[date/([0-9]{4})/?$] => index.php?year=$1
)
あとがき
このような方法で、WordpressのURLをかなり柔軟にいじれる。本来ならば、変更前のURLへのアクセスを301リダイレクトするとかも考えるべきだろうが、まあ、許してください。ほんとはこれをもっと汎用的なプラグインにしてwordpress.orgから配信できるといいんだけど、いまのところやる気が足りません。要望があれば考えます。
FC2ブログから、レンタルサーバ+独自ドメイン+WordPressに移行しました
- 2009年7月1日 11:24 PM
- 未分類
※基本的に記事やブログのトップページへのアクセスは新しいほうへリダイレクトされるはずですが、残念ながらフィードへのアクセスはどうにもできませんでした。FC2ブログのフィードを購読されてる場合、面倒ですが http://penguinlab.jp/blog/feed を購読するようにしてください。あと、FC2ブログがいつまで残っているかはわからないので、ブックマークしている場合は、新しいURLのものをブックマークしなおしてもらったほうがよいです。どうも、面倒かけてすみません。
長年、FC2ブログを使わしてもらってましたが、やはりレンタルブログ(まあいろいろ定義はあると思うが、おおむねあなたのイメージで間違ってないはず)ではカスタマイズにも限界があるので、今年の初めから借りてるレンタルサーバにWordpressをインストールして、そこに移行することにしました。(ついでに長年痛いと思ってたブログのタイトルを変えました。新しいのも痛いという指摘は甘んじて受けます。)
だいたい手順としてはこんな感じだった。
- Worpressをインストール
- テーマを探すも、リキッドレイアウトでいいものがない
- リキッドレイアウトでもいけそうな、CarringtonにCSSを追加して使うことに
- FC2ブログのエクスポート
- エクスポートしたデータの修正
- FC2ブログの画像をダウンロード(サムネイルも)
- いっかいWordpressにインポート(MovableType形式として)
- WordPressからエクスポート(WXR形式)
- wp:post_nameをFC2ブログのblog-entry-***.htmlの***部分と一致するようにする
※ここは残念ながら完全に手作業、まだ記事が200件ちょっとだからできたこと。傷は浅いうちに、です。 - WordPressのパーマリンクをpost/%postname%に変える
- 新しい記事についてはPost IDがスラッグになるように、Auto-Slugを一部改変して使う
- FC2ブログのテンプレートを編集して、リダイレクトするように設定
完全にリダイレクト用となったFC2ブログをFC2がいつまで残しといてくれるかは不安ですが、この不安はまあレンタルブログを使い続けた代償ですかね。これで、今後URLが変わる可能性はかなり低くなったので、まあ、良しとします/してください。
なお、Carringtonテーマをリキッドレイアウトにするために加えた変更は以下の通り。これをcss.phpの末尾に追加した。
.wrapper {
width: auto !important;
margin: 0 1.5em !important;
}
.section {
min-width: 0 !important;
}
#sidebar{
float:right !important;
width:198px !important;
}
#content{
margin-right: -250px !important;
width: 100% !important;
}
#content > *{
margin-right: 250px !important;
}
.full-content{
width: auto !important;
}
.full-title{
width: auto !important;
}
#all-categories{
width: auto !important;
}
#header .wrapper{
margin: 0 !important;
padding-left: 20px !important;
}
参考になったページ:
ホーム > タグ > Wordpress
- 検索
- フィード
- メタ情報
