WordPressのナビゲーションメニューは、管理画面上からドラッグ&ドロップで設定できて便利なのですが、非公開設定となっている投稿や固定ページなどが含まれている場合でも、表示の調整は行ってくれず全てが表示されてしまいます。このため、閲覧権限がないユーザーが非公開記事のメニューをクリックした場合「リンク切れか?」と思われてしまうことになります。
これでは、ユーザーエクスペリエンスもだだ下がりになってしまうので、メニューの記事が非公開の場合、自動的に表示されないようにしてみましょう。
ナビゲーションメニューには、wp_nav_menu_objects という、登録されたメニューをフィルタリングできるフックが存在しています。
今回は、ここで
- メニューが投稿タイプかどうかをチェック
- メニューの記事が非公開で、なおかつユーザーの閲覧権限がない場合、メニューを削除し、削除済みリストにメニューのIDを保持
- 子メニューだけが表示されることを防ぐため、メニューの親ID(menu_item_parent)が、削除済みリストに含まれていた場合も、メニューを削除
という処理を行います。
具体的なコードが、CODE 1。
CODE 1
function remove_private_post_menu( $sorted_menu_items ) { $unset_ids = array(); foreach ( $sorted_menu_items as $key => $item ) { if ( $item->type == 'post_type' ) { $post = get_post( $item->object_id ); $post_type = get_post_type_object( $post->post_type ); if ( $post->post_status == 'private' && ! current_user_can( $post_type->cap->read_private_posts ) ) { unset( $sorted_menu_items[$key] ); $unset_ids[] = $item->ID; continue; } } if ( in_array( $item->menu_item_parent, $unset_ids ) ) { unset( $sorted_menu_items[$key] ); $unset_ids[] = $item->ID; } } return $sorted_menu_items; } add_filter( 'wp_nav_menu_objects', 'remove_private_post_menu' );
テーマの functions.php や プラグインに記述していただければ、閲覧権限がないユーザーの場合、メニューが子メニューごとキレイさっぱり表示されなくなります。
ログイン機構を持ったサイトなどで、ユーザーの状況次第でメニューの表示を変えることにも応用が利くのではないでしょうか。