8beat Studio

Wordpress, LGBT, モンハン などにまつわる小倉の頭のなか

管理画面のカスタム投稿一覧に絞り込みできるカテゴリとタグを表示する方法

2017/02/08 -

カスタム投稿タイプを使って制作実績のページを制作中、ちょっとハマったので備忘録。
申し遅れました小倉(@ogr8beat)です。
なお、今回の記事ではカスタム投稿タイプやタクソノミーの作り方には触れていません。

タクソノミーについて復習

そのものずばり、記事をグループ化する、カテゴライズする、分類する仕組みです。
要はおなじみのカテゴリやタグなどのこと。
投稿ページを開くとカテゴリやタグの欄があるのはなぜか?

わぷー
わぷー
そうだよね、多くなるだろうしグループ分けできた方がいいよね!

…とWordPressのインストール時点で分類方法として設定してくれているためです。
いわば既定のものなので「デフォルト分類」といいます。

対して「カスタム分類」は、デフォルト分類である「カテゴリ」や「タグ」とは別にユーザ自身で設定する分類方法のこと。
とはいっても、親子関係がつけられるカテゴリ、カテゴリをまたぎ関連づけられるタグ、この2つがあれば一般的には十分ですよね。
だからまるでカスタム投稿タイプ専用のように使われがちですが、実は通常の投稿(ブログ記事)や固定ページでも使えます。

カスタム分類だとかカスタムタクソノミーだとか呼び方が複数ありますが、「分類」が英語か日本語かというだけで全くの同義語です。
スマホって呼ぶかスマフォって呼ぶかみたいな感じでしょうか。

さて、私も例に漏れず、カスタム投稿タイプでこのカスタム分類を使いました。
カテゴリ型のカスタム分類と、タグ型のカスタム分類です。
ゲシュタルト崩壊しそうなので、ここで作った2つのカスタム分類は便宜上「カテゴリ」「タグ」と呼ぶことにします。

カスタム投稿記事一覧にはタクソノミーの項目がない

ダッシュボード内、管理画面の話です。
通常の投稿記事一覧にはあるのに、カスタム投稿一覧にはカテゴリもタグも表示されていません。
ユーザが自身で追加した分類方法の紐づけをWordPressに認識させてやらないといけないんですね。
通常の投稿(ブログ記事)と同じようにするとなると、必要なのは以下。

  • カテゴリとタグどちらも表示
  • タームが複数あるなら全て表示
  • クリックで同じタームの記事を絞り込み

ここで「ターム」という新しいワードが出てきましたが、なんてことありません。
「中華」というカテゴリのタームは「中華」、「ラーメン」というタグのタームは「ラーメン」です。
うまい言い方が思いつきませんが、分類に使う文字列そのもののようなイメージです。

Codexのダイアグラムを参考に作成

タクソノミーとタームの関係性については次のサイトが分かりやすいかなと思います。
カスタム投稿タイプやカスタム分類を作るコードも記載されていたので、それについてはこちらを参照してください。
参考カスタム投稿タイプ、カスタムタクソノミーについて整理してみた - 初心者にもおすすめ!無料 WordPress テーマ Principle

コードを書いてカテゴリとタグを追加

では、本題のカテゴリとタグを表示させるコードについてです。
それには前提として、いくつかのスラッグを把握しておく必要があります。
カスタム投稿タイプ、カテゴリとタグそれぞれのスラッグ、つまり英語版の名前です。

  1. 「レシピ」というカスタム投稿タイプで、スラッグは「recipe
  2. レシピを和食とか洋食とか分類するためのカテゴリ、スラッグは「recipe-category
  3. レシピを麺類とか肉料理とか縦横無尽に分類するためのタグ、スラッグは「recipe-tag

上記を例にして、さっそくサンプルコードです。
もちろん functions.php に書くのでバックアップなどの事前準備は各自行ってください。

PHP

//管理画面のカスタム投稿一覧にカテゴリとタグを表示
function add_posts_columns($columns) {      //関数・変数は適当
    $columns['recipe_category'] = 'カテゴリ';   //カスタム分類のスラッグ
    $columns['recipe_tag'] = 'タグ';          //カスタム分類のスラッグ
    return $columns;
}
function add_posts_columns_list($column_name, $post_id) {   //関数・変数は適当
    if ( 'recipe_category' == $column_name ) {
        $terms = $terms = get_the_terms( $id, 'recipe_category' );
        $cnt = 0;
        foreach((array)$terms as $var) {
            echo $cnt != 0 ? ", " : "";
            echo "<a href=\"" . get_admin_url() . "edit.php?recipe_category=" . $var->slug . "&post_type=recipe" . "\">" . $var->name . "</a>";
            ++$cnt;
        }
    } elseif ( 'recipe_tag' == $column_name ) {
        $terms = $terms = get_the_terms( $id, 'recipe_tag' );
        $cnt = 0;
        foreach((array)$terms as $var) {
            echo $cnt != 0 ? ", " : "";
            echo "<a href=\"" . get_admin_url() . "edit.php?recipe_tag=" . $var->slug . "&post_type=recipe" . "\">" . $var->name . "</a>";
            ++$cnt;
        }
    }
}
add_filter( 'manage_edit-recipe_columns', 'add_posts_columns' );
add_action( 'manage_recipe_posts_custom_column', 'add_posts_columns_list', 10, 2 );

各スラッグの部分を書き換えればコピペで実装できると思います。
なお、サンプルコード内のコメントどおり関数名(add_posts_columnsadd_posts_columns_list)、変数名($columns など)は自分が分かりやすい好きな文字列に変えることもできます。

  • 複数のカテゴリ、複数のタグをつけるケースを想定して foreach
  • 下書き中だったり、タグなし記事などの配列データがないケースを想定して null チェックのエラーを回避
  • 自分用メモ:一番ハマったのは get_the_term_list() でターム…と思ったらフロントエンドページにリンクされたところ

思いのほか時間をかけてしまったので、このシェアで皆さんの検索時間が少しでも短縮されれば幸いです。

WordPress