てっきんの具。

「てっきん」と呼ばれて40年のおっさんが書くブログ

カスタム投稿のページ送りが 404 Not Found!の対処法

[2013.9.12追記]
初出からずいぶんたって、今ではWordPress 3.3から登場した「pre_get_posts」フックを使う方法が主流となってきました。記事の後半にサンプルコードとともに追記しましたのでご参照ください。


[初出時のテキスト]

WordPress 3.0で導入された新機能の一つ「カスタム投稿タイプ」。本格的に使ってみようという段になって、思わぬ壁にぶつかってしまいました。「カスタム投稿タイプ」で作った投稿群をカテゴリアーカイブで表示したとき、ページ送り(ページネーション)つまり

http://www.example.com/archives/category/foo/page/N(Nは数字)

といったURIで表記されるページが404 Not Foundを返すのです。

結論からいうとこの問題、『Custom Post Type Category Pagination Fix』というプラグインで解消することができました。そこで、カスタム投稿タイプの設定やコードなども交えて、解決までの道のりを紹介しようと思います。同じような悩みでぶつかっている方のご参考になれば。

今回作成したカスタム投稿タイプを仮に「foo」とします。設定には『Custom Post Type UI』プラグインを使い、以下のように設定しました。

  • 名前……foo
  • 一般公開……true
  • UIを表示……true
  • 利用タイプ……post
  • 階層……false
  • リライト……true
  • カスタムリライトスラッグ……bar
  • クエリーバージョン……true(注:query_var〔=クエリー変数〕の誤訳と思われる)
  • ビルトイン分類……「カテゴリー」「種類」

ビルトイン分類に出てくる「種類」は、同じく『Custom Post Type UI』プラグインで設定した「カスタム分類」のラベルです。

また、カテゴリーとして「hoge」を追加、カテゴリースラッグを「bar」としました。

さらに、パーマリンク設定を

http://www.example.com/archives/%post_id%

の形式にしているわたしにとっては、カスタム投稿タイプの個別ページが

http://www.example.com/archives/投稿タイトル(または投稿スラッグ)

になるのが堪えられないので『Custom Post Permalinks』プラグインを追加。パーマリンク設定で「Custom Permalink for foo」の欄を

/%post_type%/%post_id%

に設定して、通常の投稿と同様にURIが表示されるようにしました。

さて、カテゴリー「hoge」(スラッグは「bar」)のアーカイブテンプレート(category-bar.php)。メッセージループの冒頭にこんな感じで記述します。

<?php
$paged = get_query_var( 'paged' );
query_posts( "post_type=foo&posts_per_page=5&paged=$paged" );
?>

で、ここまで仕込むと

  • http://www.example.com/archives/%post_id%……個別記事
  • http://www.example.com/archives/category/foo……カテゴリーアーカイブの1ページ目
  • http://www.example.com/archives/category/foo/page/N……カテゴリーアーカイブのNページ目

が出るはずなのですが……3ページ目以降のページ送りに失敗してしまう、というわけです。

さあ、前置きが長くなりましたがこの問題を解決してくれたプラグインが『Custom Post Type Category Pagination Fix』でした。公式のプラグインディレクトリに上がっている、このようなプラグインです。

Fixes a bug in WordPress 3 ( possibly in lower versions ) when viewing a category listing page pagination, consisting of custom post types, when using the permalink structure %category%/%postname%. After the first page, the URL will be something like cat-name/page/2 and will return a 404 error page. The problem is that the request is only checking for posts with post type ‘post’, within the specified category. By adding all custom post types to the request, pagination will work as expected.

《ざっくり意訳》
カスタム投稿タイプのパーマリンク設定を %category%/%postname% 形式で設定したとき、カテゴリーリストのページ送りがうまくいかないバグを解消するプラグインです。

このバグは、カテゴリーリストの2ページ目が cat-name/page/2 みたいなURLになったときに404エラーを返すというもの。というのもWordPressは、カテゴリーリスト表示のリクエストが投げられたとき、post_typeが「post」になっている記事だけをデータベースから引っぱってくるからなんです。なので、ここにカスタム投稿タイプの記事も引っぱるようにいじってやることで、ページ送りがうまくいくようにしてるというわけです。

ちなみにこのバグ、WordPressのバージョン3、ひょっとしたらその前のバージョンでも起こるみたい。

……ということで同様の悩みをお持ちの方、一度『Custom Post Type Category Pagination Fix』を使われてはいかがでしょうか? あ、書き忘れてましたが、ページ送りのリンク生成には『WP-PageNavi』プラグインを使いました。

WordPress › Custom Post Type Category Pagination Fix « WordPress Plugins
http://wordpress.org/extend/plugins/custom-post-type-category-pagination-fix/


[2013.9.12追記]
お使いのテーマの functions.php に下記のコードを追記してください。is_main_query や pre_get_posts についての詳細は、別途ググッていただければとおもいます。

<?php

/*
 * 表示条件を query_posts() や get_posts() でなく pre_get_posts() で制御
 * 
 * この例では、投稿タイプ「foo」のアーカイブページのときに5件の記事を表示する。
 * 管理画面の[設定]-[表示設定]で設定した値は無視される。
 */

add_action( 'pre_get_posts', 'my_pre_get_posts' );
function my_pre_get_posts( $query ) {
	if ( is_admin() || ! $query -> is_main_query() ) return;

	if ( $query -> is_archive() && get_query_var( 'post_type' ) === 'foo' ) {
		$query -> set( 'posts_per_page', '5' );
	}
}

カテゴリー:

,

タグ:

コメントを残す

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

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください