WordPressのカスタム投稿タイプのアーカイブをパーマリンクで表示できるようにしてみた

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' );

あと、表示はできるとして、このパーマリンクの生成方法考えなくちゃですね。(汗

参考サイト

「WordPressのカスタム投稿タイプのアーカイブをパーマリンクで表示できるようにしてみた」への5件のフィードバック

  1. 私のところのWordPress3.14でパーマリンクをデフォルト以外でも上手く動きませんでした。月別ではなく、指定したカスタム投稿タイプが全て表示されます。どうも$year, $monthnumの取得に失敗しているようなので以下のように$mを使うように修正して使っています。

    &year=$matches[1]&monthnum=$matches[2]

    &m=$matches[1]$matches[2]

  2. 初めまして
    カスタム投稿のアーカイブで苦戦していて、このサイトのたどり着きました。

    カスタム投稿タイプの年別アーカイブの場合
    /custom_post_slug/date/nnnn/

    これは上手く行きました。
    投稿者別のアーカイブを創りたいのですが、その場合は、
    /custom_post_slug/author/
    となると思うのですが、どのようにすれば実現できますでしょうか?

  3. 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つを追加します。
    追加する内容は、上記の投稿の作成者別アーカイブのマッピングデータを流用し、左辺は、

    • 最初に / を追加する
    • 最後の ?$ は、23行目で追加しているので削除する

    右辺は、

    • index.php? の部分を & に変更する

    で、実現できるかと思います。

    適用したマッピングルールが、WordPressで正しく適用できているか、またURLが正しく変換できるかなどは、Rewrite Rules Inspector というプラグインが便利です。

    [参考]
    WordPress での URL rewrite の挙動を確認できる Rewrite Rules Inspector

  4. 早速のレス、ありがとうございます。

    早速、試してみます。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です