WordPressのメディアライブラリ(attachment)にカスタムタクソノミーを登録して、フロントにギャラリー的なページを作ったとき、ページネーションの2ページ目以降が404になる問題にハマりました。
調べてもなかなか情報が出てこなかったので、原因と解決方法をまとめます。
環境
- WordPress(テーマは自作)
- メディアライブラリ(attachment)にカスタムタクソノミー
media_catを登録 - タクソノミーアーカイブでページネーションを使用
カスタムタクソノミーの登録
functions.phpにカスタムタクソノミーを登録します。
function add_tax_mediacat() {
register_taxonomy(
'media_cat',
'attachment',
array(
'label' => 'MediaCategories',
'show_ui' => true,
'show_in_menu' => true,
'hierarchical' => true,
'show_admin_column' => true,
'update_count_callback' => '_update_generic_term_count',
'query_var' => true,
'rewrite' => array(
'slug' => 'library',
'hierarchical' => true
),
'has_archive' => true,
'sort' => true,
)
);
}
add_action( 'init', 'add_tax_mediacat' );
問題
タクソノミーアーカイブの1ページ目は表示される。しかし、ページ送りで2ページ目(library/camera/film/page/2/)にアクセスすると404エラーになる。
原因
WordPressのメインクエリは、デフォルトではattachmentの投稿タイプを対象にしません。タクソノミーアーカイブのメインクエリがpost_typeを通常のpostとして処理するため、attachmentの投稿が見つからず、2ページ目以降で「投稿がない」と判定されて404になります。
テンプレート側(archive.phpやtaxonomy.php)でカスタムクエリを書いていても、WordPressの404判定はメインクエリに基づいて行われるので、テンプレート側の記述だけでは解決しません。
解決方法
pre_get_postsフックでメインクエリを書き換えます。
function fix_attachment_taxonomy_pagination($query) {
if ( is_admin() || ! $query->is_main_query() ) {
return;
}
if ( $query->is_tax('media_cat') ) {
$query->set( 'post_type', 'attachment' );
$query->set( 'post_mime_type', 'image/jpeg' );
$query->set( 'post_status', 'inherit' );
}
}
add_action( 'pre_get_posts', 'fix_attachment_taxonomy_pagination' );
ポイント
post_typeをattachmentに指定して、メインクエリの対象をメディアに変更post_statusをinheritにする(attachmentのデフォルトステータスはinheritで、publishではない)post_mime_typeは必要に応じて変更(画像以外も含める場合は削除)is_tax('media_cat')で対象のタクソノミーに絞ることで、他のアーカイブに影響を与えない
合わせて確認すること
- パーマリンクの空更新: 設定 → パーマリンク設定 → 何も変えずに「変更を保存」。リライトルールが再生成される
- 表示件数: 設定 → 表示設定 → 1ページに表示する最大投稿数。これが実際の投稿数より多いとページネーション自体が出ない
まとめ
attachmentにカスタムタクソノミーを使うケース自体がWordPressではマイナーなので、情報が少なくてハマりやすいポイントです。核心は「メインクエリがattachmentを対象にしていないこと」で、pre_get_postsで書き換えるのが正攻法です。