拡張の1つが、カスタムフィールド と呼ばれるもので、投稿記事に独自の属性を追加できるもの。
さらに、WordPress3.0からは カスタム投稿タイプ/カスタムタグソノミー というものが独自に追加できるようになっています。
WordPressは、[投稿]と[固定ページ]の2つのページの種類がありますが、それを増やすことが出来るのが カスタム投稿タイプ。
それらのページに [Category]という分類を設定できるのですが、[Category]以外の分類を増やす事が出来るのがカスタムタグソノミー。
カスタム投稿タイプ/カスタムタグソノミー を使うと、ブログシステムの枠を超えて、簡単なシステムを作る事ができるようになります。
記事を投稿する画面や、分類毎にページを作成するphpの振り分けはwordpressに任せてあとは自作という感じに。
ここ、3ヶ月ほどWordPressを使ってみて、カスタム投稿タイプ/カスタムタグソノミー も使ってみたりしていたのですが、よくハマったのがパーマリンク。
WEBページでのパーマリンクはREST風にちゃんと設定したくなるので...
WordPressでは、デフォルトの記事のリンクは
http://localhost?post_type={投稿タイプ}&p={投稿のID}
のような感じになっています。これを
http://localhost/sample/test
のようなリンクにするために、URLのRewrite をガシガシ行なって表示します。
WordPressではこのRewriteルールを自動的に設定or管理画面より設定できるようになっています。
たとえば、以下のような設定がWordpressから設定されます。
category/(.+?)/page/?([0-9]{1,})/?$' => string 'index.php?category_name=$matches[1]&paged=$matches[2]
WordPressのデフォルトのRewriteルールの設定は、管理画面のパーマリンクの設定を更新した時に行われると思うので、なんかリンク系を変更した時 とか データを他のサーバーに移行した時 などでは とりあえず更新しておくのが無難。
まぁ、それでも、うまく動かなくなったり、独自のルールにしたくなったり するのでお相手する必要があるのですけども。
ハマったことを中心に。
カスタムタグソノミーもパーマリンクの一部にしたい
デフォルトの投稿タイプ(post)では、カテゴリをパーマリンクの一部にできます。だが、カスタム投稿タイプのときは...一番いい方法かどうかは不明ですが...以下でできます。
register_post_type で、
'rewrite' => array( 'slug' => CUSTOM_POST_TYPE.'/%'.CUSTOM_TAXONOMY.'%', 'hierarchical' => false ),
と指定しておいて、
add_filter('post_link', 'rating_permalink', 10, 3); add_filter('post_type_link', 'rating_permalink', 10, 3); function rating_permalink($permalink, $post_id, $leavename) { if (strpos($permalink, '%'.CUSTOM_TAXONOMY.'%') === FALSE) return $permalink; $post = get_post($post_id); if (!$post) return $permalink; if ($post->post_type != CUSTOM_POST_TYPE) return $permalink; $terms = wp_get_object_terms($post->ID, CUSTOM_TAXONOMY); if (!is_wp_error($terms) && !empty($terms) && is_object($terms[0])) $taxonomy_slug = $terms[0]->slug; else $taxonomy_slug = 'not-rated'; return str_replace('%'.CUSTOM_TAXONOMY.'%', $taxonomy_slug, $permalink); }無理やり埋め込んであげている感じですねw
ただし、上記の方法だと、投稿IDをキーにパーマリンクを取得(get_permalink)する時にうまく反応してくれないことがあるので注意。
カスタム投稿タイプのパーマリンクの設定
カスタム投稿タイプの場合、register_post_type という関数を使って登録した後、
flush_rewrite_rules();
を行うと、Rewriteルールを追加してくれます。逆にこれを実行しないと追加されない。
まぁココまではいいのですが、複数のカスタム投稿タイプをつくった場合、登録した後にすぐに上記を複数回実行すると、環境によっては反映が不十分で、パーマリンク設定が未設定のものができてしまう現象に遭遇。
カスタム投稿タイプの登録(register_post_type)は、add_action('init', ***)のアクションフックで処理し、
flush_rewrite_rules は initの後に実行される add_action('wp_loaded', ***)で1回実行することにより解決しました。
あるはずのリンクが404になる
http://localhost?post_type={投稿タイプ}&p={投稿のID}のような形式ならみれるけど、
http://localhost/sample/test
のような形式だと404になるのであれば、RewriteRuleがうまく設定されていない問題。
あるある。めっちゃよくある。
こういう時は繰り返しになるけど、
- 管理画面のパーマリンクを更新してみる
- カスタム投稿タイプの時には flush_rewrite_rules が実行されているかみる
- global $wp_rewrite を var_dump してルールの中身を確認してみる
な感じでさぐれば解決できるはず。たぶん。
http://localhost/****/****/page/2 のようなURLで2ページ目が表示されないという場合は
他のマッチパターンに引っかかってしまってダメな時もあります。
**** の部分が自由に設定できるような時は、page という名前の投稿名なのか pageの設定なのかが判断つかないよーな感じ。
WordPress.org Using Permalinksを見ると、
http://www.example.com/page/2/
http://www.example.name/category/categoryname/page/2/
http://www.example/year/month/day/page/2/
http://www.example/year/month/page/2/
の例が書かれてますね。
パーマリンクを変えたい
よくあるのが、カテゴリページのURLの category というのを削除したいというパターンhttp://localhost/cateogry/fruit
↓
http://localhost/fruit
Top Level Categories ってプラグインを使うと消すことができます。
もっと自由に設定したいんだ! というときには Rewriteルールを書いちゃう手も。
add_filter( 'rewrite_rules_array','my_insert_rewrite_rules' );
function my_insert_rewrite_rules($rules) {
$newrules = array();
$newrules['fruit/?$'] = 'index.php?category_name=fruit';
return $newrules + $rules;
}
とか。
パーマリンクの形式は事前に検討して、
全体的に整合性がとれるか? (=自分で正規表現でマッチパターンがかけるか?)
をしておくのは大事。
これができていれば、最悪なんとか頑張ればできるはず...と思う。