WordPressのカスタム投稿タイプは、投稿などと切り分けられて便利ではあるのですが、パーマリンク利用時にカスタム投稿の一覧や年月アーカイブの表示に困ったりすることになります。
WordPressのパーマリンクというのは、アクセスされたURLをもとに、デフォルトのURLのパターンに変換し、内部処理を行っています。
カスタム投稿タイプについても、デフォルトのパーマリンクでは、?post_type=custom
や?post_type=custom&year=2011&monthnum=04
で表示出来るので、簡単に言うと、パーマリンクのURLから、左記で示したデフォルトのURLに変換できるようにマッピングさせてあげれば良いのです。
CODE 1は、デフォルト以外の投稿タイプで、投稿タイプの一覧や、投稿タイプの年月アーカイブが表示できるようにするコードです。
- /custom_post_slug/
- カスタム投稿タイプの一覧を表示します。
- /custom_post_slug/date/nnnn/
- カスタム投稿タイプの年別アーカイブを表示します。
- /custom_post_slug/date/nnnn/nn/
- カスタム投稿タイプの月別アーカイブを表示します。
- /custom_post_slug/date/nnnn/nn/nn/
- カスタム投稿タイプの日別アーカイブを表示します。
投稿タイプによってはページ的に扱うものもあるはずなので、必ずしもアーカイブ表示が必要になるとは思いませんが、そこは今後の課題でしょうか。判別するとすれば、投稿タイプ登録時のsupportsにpage-attributesが含まれているかどうかあたりが適切かもしれません。
CODE 1
function check_custom_rules() { global $wp_rewrite, $add_cutom_post_rules; if ( ! $wp_rewrite->using_permalinks() ) { return; } $add_cutom_post_rules = array(); $rule_templates = array( '/' => '', '/([0-9]{1,})/' => '&p=$matches[1]', '/page/([0-9]{1,})/' => '&paged=$matches[1]', '/date/([0-9]{4})/' => '&year=$matches[1]', '/date/([0-9]{4})/page/([0-9]{1,})/' => '&year=$matches[1]&paged=$matches[2]', '/date/([0-9]{4})/([0-9]{2})/' => '&year=$matches[1]&monthnum=$matches[2]', '/date/([0-9]{4})/([0-9]{2})/page/([0-9]{1,})/' => '&year=$matches[1]&monthnum=$matches[2]&paged=$matches[3]', '/date/([0-9]{4})/([0-9]{2})/([0-9]{2})/' => '&year=$matches[1]&monthnum=$matches[2]&day=$matches[3]', '/date/([0-9]{4})/([0-9]{2})/([0-9]{2})/page/([0-9]{1,})/' => '&year=$matches[1]&monthnum=$matches[2]&day=$matches[3]&paged=$matches[4]', ); $post_types = get_post_types( array( 'public' => true, 'show_ui' => true ), false ); if ( $post_types ) { foreach ( $post_types as $post_type_slug => $post_type ) { if ( ! isset( $post_type->_builtin ) || ! $post_type->_builtin ) { foreach ( $rule_templates as $regex => $rule ) { $add_cutom_post_rules[ $post_type_slug . $regex . '?$' ] = $wp_rewrite->index . '?post_type=' . $post_type_slug . $rule; } } } } if ( $add_cutom_post_rules ) { $rules = $wp_rewrite->wp_rewrite_rules(); foreach ( $add_cutom_post_rules as $regex => $rule ) { if ( ! isset( $rules[$regex] ) ) { $wp_rewrite->flush_rules(); break; } } } } add_action( 'init', 'check_custom_rules' ); function add_custom_type_index_rules( $rules ) { global $add_cutom_post_rules; if ( $add_cutom_post_rules && is_array( $add_cutom_post_rules ) ) { $rules = array_merge( $add_cutom_post_rules, $rules ); } return $rules; } add_filter( 'rewrite_rules_array', 'add_custom_type_index_rules' );
あと、表示はできるとして、このパーマリンクの生成方法考えなくちゃですね。(汗
私のところのWordPress3.14でパーマリンクをデフォルト以外でも上手く動きませんでした。月別ではなく、指定したカスタム投稿タイプが全て表示されます。どうも$year, $monthnumの取得に失敗しているようなので以下のように$mを使うように修正して使っています。
&year=$matches[1]&monthnum=$matches[2]
↓
&m=$matches[1]$matches[2]
初めまして
カスタム投稿のアーカイブで苦戦していて、このサイトのたどり着きました。
カスタム投稿タイプの年別アーカイブの場合
/custom_post_slug/date/nnnn/
これは上手く行きました。
投稿者別のアーカイブを創りたいのですが、その場合は、
/custom_post_slug/author/
となると思うのですが、どのようにすれば実現できますでしょうか?
WordPressの投稿の作成者別アーカイブは、/author/jim912/ のようになりますね。
この場合のWordPress 内部のマッピングルールは、以下の様になっています。
"author/([^/]+)/page/?([0-9]{1,})/?$" => "index.php?author_name=$matches[1]&paged=$matches[2]"
"author/([^/]+)/?$" => "index.php?author_name=$matches[1]"
1つ目がアーカイブでページ送りをした場合のもの、2つ目が1ページ目のものになります。
これが処理された場合、author に続く ([^/]+) の部分が、$matches[1] として、author_name というパラメーターとして扱われるように変換されています。
カスタム投稿タイプについては、このルールに、投稿タイプのパラメーター post_type を追加するだけで対応できます。
具体的には、CODE 1 の $rule_templates に、作成者別アーカイブ用のマッピングデータ2つを追加します。
追加する内容は、上記の投稿の作成者別アーカイブのマッピングデータを流用し、左辺は、
右辺は、
で、実現できるかと思います。
適用したマッピングルールが、WordPressで正しく適用できているか、またURLが正しく変換できるかなどは、Rewrite Rules Inspector というプラグインが便利です。
[参考]
WordPress での URL rewrite の挙動を確認できる Rewrite Rules Inspector
早速のレス、ありがとうございます。
早速、試してみます。