【WordPress】サブメニューとして表示したカスタム投稿のカテゴリー表示
カスタム投稿をサブメニューとして登録した場合、タクソノミー(カテゴリー)を管理画面メニュー上に表示するのがややこしいのでまとめました。
目指す状態
目標としては図のような状態です。
いろいろあって特定のカスタム投稿(カスタム投稿1)のサブメニューとして別のカスタム投稿(カスタム投稿2)を登録してあります。親になるトップレベルメニューはプラグインの設定画面なり、いろいろなパターンがあると思います。
この記事では、カスタム投稿2のカテゴリーをサブメニューに表示させる方法を見ていきます。
カスタム投稿をサブメニューとして登録
まず、カスタム投稿1のサブメニューとしてカスタム投稿2をぶら下げる処理。
register_post_type
のshow_in_menu
にカスタム投稿1の/wp-admin/
以降の文字列を指定する。
‘tools.php’ や ‘edit.php?post_type=page’ のようなトップレベルのページを指定すると、この投稿タイプをそのサブメニューに配置する。
関数リファレンス/register post type – WordPress Codex 日本語版
add_action( 'init', 'register_post_types' );
function register_post_types(){
register_post_type( 'sample1',
array(
'label' => 'カスタム投稿1',
'public' => true,
)
);
register_post_type( 'sample2',
array(
'label' => 'カスタム投稿2',
'public' => true,
'show_in_menu' => 'edit.php?post_type=sample1',
)
);
}
この状態になります。
- register_post_type() | Function | WordPress Developer Resources
- 関数リファレンス/register post type – WordPress Codex 日本語版
カスタム投稿にタクソノミーを追加
トップレベルメニューのカスタム投稿の場合
トップレベルメニューにあるカスタム投稿1であれば、以下のようにするだけでカテゴリーが追加される。
register_taxonomy( 'sample1-cat', 'sample1', array(
'label' => 'カスタム投稿1のカテゴリー',
'public' => true,
'hierarchical' => true,
));
サブメニューのカスタム投稿の場合
しかしカスタム投稿2では同様にしても、メニューにカテゴリーが表示されない。
register_taxonomy( 'sample2-cat', 'sample2', array(
'label' => 'カスタム投稿2のカテゴリー',
'public' => true,
'hierarchical' => true,
));
ここで/wp-admin/edit-tags.php?taxonomy=sample2-cat
のURLを直接叩くと編集画面を表示することができる。
つまりタクソノミー自体は追加されているが、メニューに表示されない状態になっている。
show_in_menu は効かない
register_taxonomy()
のCode Referenceを参照すると、パラメータにregister_post_type
と同様のshow_in_menu
が見つかる。ので、ここに同じように文字列を入れたくなるが、true or false の2択となっていて同じように指定できない。
register_taxonomy( 'sample2-cat', 'sample2', array(
'label' => 'カスタム投稿2のカテゴリー',
'public' => true,
'hierarchical' => true,
'show_in_menu' => 'edit.php?post_type=sample1', // 効かない
));
- register_taxonomy() | Function | WordPress Developer Resources
- 関数リファレンス/register taxonomy – WordPress Codex 日本語版
サブメニューのカスタム投稿のタクソノミーを表示させる
add_submenu_page
をアクションフックadmin_menu
にフックして使用する。
第一引数の$parent_slug
にはregister_post_type
のshow_in_menu
に設定したものと同様の文字列を指定する。
5番目の$menu_slug
にはカテゴリーページ自身のスラッグ(edit-tags.php?taxonomy={タクソノミ名}
)を指定する。
add_action( 'admin_menu', 'show_taxonomy_under_specific_menu' );
function show_taxonomy_under_specific_menu(){
add_submenu_page(
'edit.php?post_type=sample1', // $parent_slug
'カスタム投稿2のカテゴリー', // $page_title
'カスタム投稿2のカテゴリー', // $menu_title
'manage_options', // $capability
'edit-tags.php?taxonomy=sample2-cat&post_type=sample2' // $menu_slug
);
}
表示された。
タクソノミー編集ページ表示時に正しい親メニューと紐付ける
しかし追加された「カスタム投稿2のカテゴリー」のメニューをクリックすると…
ページは正しく遷移するが、メニューバーが紐づいておらず、「投稿」のメニューが選択された状態になってしまうため修正する。
「このサブメニューの親(トップレベルメニュー)はこれだよ」というのを指定する$parent_file
という変数があり、/wp-admin/menu-header.php
でフックが用意されているので、正しい親を紐付ける。
add_filter( 'parent_file', 'set_parent_file' );
function set_parent_file( $parent_file ){
global $current_screen;
$taxonomy = $current_screen->taxonomy;
if ( $taxonomy == 'sample2-cat' ) {
$parent_file = 'edit.php?post_type=sample1';
}
return $parent_file;
}
正しく紐づいた状態。
- /wp-admin/menu-header.php
- parent_file | Hook | WordPress Developer Resources
- php – WordPress show taxonomy under custom admin menu – Stack Overflow
タクソノミー編集ページ表示時にサブメニューを太字にする
カテゴリー編集ページに居る際に、メニューが太字(current)にならない。
上記状態では、「カスタム投稿2のカテゴリー」編集ページ表示を開いているにもかかわらず、メニューが太字でハイライトされない。
これは/wp-admin/menu-header.php
の以下の箇所の比較で失敗しているため。
if ( isset( $submenu_file ) ) {
if ( $submenu_file == $sub_item[2] )
$class[] = 'current';
...
}
上記でそれぞれの変数には以下が入っており、イコールにならない。
- $submenu_file → string(56) “edit-tags.php?taxonomy=sample2-cat&post_type=sample2”
- $sub_item[2] → string(52) “edit-tags.php?taxonomy=sample2-cat&post_type=sample2”
そこでフィルターフックsubmenu_file
で$submenu_fileにエスケープされていない値を入れ直す。
add_filter( 'submenu_file', 'highlight_taxonomy_menu' );
function highlight_taxonomy_menu( $submenu_file ){
if( esc_html( 'edit-tags.php?taxonomy=sample2-cat&post_type=sample2' ) == $submenu_file ){
$submenu_file = 'edit-tags.php?taxonomy=sample2-cat&post_type=sample2';
}
return $submenu_file;
}
完成。
- submenu_file | Hook | WordPress Developer Resources
- Manually highlight WordPress admin menu item – Stack Overflow
post_typeのパラメータを付けない場合
以下のように&post_type=sample2
のパラメータを付けなかった場合でも、メニューは正しく表示される。
add_action( 'admin_menu', 'show_taxonomy_under_specific_menu' );
function show_taxonomy_under_specific_menu(){
add_submenu_page(
'edit.php?post_type=sample1', // $parent_slug
'カスタム投稿2のカテゴリー', // $page_title
'カスタム投稿2のカテゴリー', // $menu_title
'manage_options', // $capability
//'edit-tags.php?taxonomy=sample2-cat&post_type=sample2' // $menu_slug
'edit-tags.php?taxonomy=sample2-cat' // $menu_slug
);
}
ただしこの場合、「カウント」のリンクが正しく紐づかず、通常の「投稿」(post_type=post)でタクソノミーを探しに行ってしまうので、post_typeのラメータは省略しない方が良い。
一番いいのは…
そもそも普通にメインメニューとして扱っていいなら、こんなややこしいことする必要ないので、まずはこうして差し支えないか確認するのがよいと思いました。