【WordPress】attachmentにカスタムタクソノミーを使うとページネーションが404になる問題と解決法

/

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.phptaxonomy.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_typeattachmentに指定して、メインクエリの対象をメディアに変更
  • post_statusinheritにする(attachmentのデフォルトステータスはinheritで、publishではない)
  • post_mime_typeは必要に応じて変更(画像以外も含める場合は削除)
  • is_tax('media_cat')で対象のタクソノミーに絞ることで、他のアーカイブに影響を与えない

合わせて確認すること

  • パーマリンクの空更新: 設定 → パーマリンク設定 → 何も変えずに「変更を保存」。リライトルールが再生成される
  • 表示件数: 設定 → 表示設定 → 1ページに表示する最大投稿数。これが実際の投稿数より多いとページネーション自体が出ない

まとめ

attachmentにカスタムタクソノミーを使うケース自体がWordPressではマイナーなので、情報が少なくてハマりやすいポイントです。核心は「メインクエリがattachmentを対象にしていないこと」で、pre_get_postsで書き換えるのが正攻法です。