長ったらしいタイトルですみません。。
大なごやWeb会議の運営メンバーで、スライム色のニョロニョロのキャラを持ち、「マイスペースクリエイター」とよく間違われるマイペースクリエイターさんがゆるぼっていたので、ちょいと調べてみました。
まずは、ゆるぼツイートだけでは具体的なことが分からなかったので、聞いてみると、
とのこと。
どうやら、
- 表示設定のフロントページの表示で投稿ページの設定を行っていて、なおかつその投稿ページがナビメニューに登録されている場合、カスタム投稿タイプのページを表示している際にも、投稿ページのメニューに current_page_parent のクラスが付いてしまっているので消したい。
- 施工実績という固定ページにてテンプレート内でクエリーを発行しカスタム投稿タイプの一覧を表示させているが、カスタム投稿タイプの詳細表示において、施工実績の固定ページのナビメニューに current_page_parent が付くようにしたい。
ということらしいです。
で、小一時間で作成したコードがこれ。ナビメニューの各リストに付くclass属性をフィルタリングできるnav_menu_css_classにフックし、条件に応じてcurrent_page_parentの削除・追加をするようにしています。
function mypace_custom_navi_menu( $classes, $item, $args ) { $page_for_posts = get_option( 'page_for_posts' ); if ( is_singular( 'construction' ) ) { if ( is_numeric( $page_for_posts ) && $item->object_id == $page_for_posts && $item->object == 'page' && $key = array_search( 'current_page_parent', $classes ) ) { unset( $classes[$key] ); } elseif ( $item->title == '施工実績' && $item->object == 'page' ) { $classes[] = 'current_page_parent'; } } return $classes; } add_filter( 'nav_menu_css_class', 'mypace_custom_navi_menu', 10, 3 );
一応、これで運用環境では問題ないようなのですが、カスタム投稿タイプの表示でも、投稿ページのメニューに current_page_parent が付いてしまうのが、解せなかったため、どういうロジックで投稿ページの current_page_parent が付くのかソースを追ってみることにしました。
該当箇所は、wp-includes/nav-menu-template.phpの396-398行目(ver 3.1.2)、_wp_menu_item_classes_by_context関数にあるコードです。
// back-compat with wp_page_menu: add "current_page_parent" to static home page link for any non-page query if ( ! empty( $home_page_id ) && 'post_type' == $menu_item->type && empty( $wp_query->is_page ) && $home_page_id == $menu_item->object_id ) $classes[] = 'current_page_parent';
ここで、$home_page_id は投稿ページのIDなので、投稿ページのメニューか否かの判断以外では、$wp_query->is_pageがない、つまり固定ページでなければ current_page_parent を付けるというロジックになっています。
カテゴリーやタグはまだしも、カスタム投稿タイプ、カスタム分類、アタッチメントや検索結果の表示でも、投稿ページのメニューに current_page_parent が付いてしまうって、どういうことなのさ。。。
事実、WordPressのtracでも、この件は報告されているので、今後のバージョンでは、修正されるかもしれません。
Ticket #16382 Menus adds “current_page_parent” class to the blog page when viewing a custom post type entry
ただ、Milestone が Future Release になっていて、すぐさま直される可能性は高くないので、最初のコードをリファクタリングして、他の状況(カスタム分類とかね)においても正しく動作するようにしてみました。
function mypace_custom_navi_menu( $classes, $item ) { global $wp_query; $singular_slug = 'construction'; $page_for_custom_type_title = '施工実績'; $page_for_posts = get_option( 'page_for_posts' ); $post_type_query = $wp_query->query_vars['post_type']; $del_flag = true; $add_flag = false; if ( is_singular( 'post' ) || is_category() || is_tag() ) { $del_flag = false; } elseif ( ( is_author() || is_date() || is_author() ) ) { if ( in_array( $post_type_query, array ( '', 'post' ) ) ) { $del_flag = false; } elseif ( $post_type_query == $custom_post_type ) { $add_flag = true; } } elseif ( is_tax() ) { $taxonomy = get_taxonomy( $wp_query->query_vars['taxonomy'] ); if ( count( $taxonomy->object_type ) == 1 && $taxonomy->object_type[0] == 'post' ) { $del_flag = false; } elseif ( count( $taxonomy->object_type ) == 1 && $taxonomy->object_type[0] == $singular_slug ) { $add_flag = true; } } elseif ( is_singular( $singular_slug ) ) { $add_flag = true; } if ( $del_flag && is_numeric( $page_for_posts ) && $item->object_id == $page_for_posts && $item->object == 'page' && $key = array_search( 'current_page_parent', $classes ) ) { unset( $classes[$key] ); } elseif ( $add_flag && $item->title == $page_for_custom_type_title && $item->object == 'page' ) { $classes[] = 'current_page_parent'; } return $classes; } add_filter( 'nav_menu_css_class', 'mypace_custom_navi_menu', 10, 2 );
上記は、マイペースクリエイターさん独自の環境(【改正版】カスタム投稿タイプの表示用のページを作る-WordPress備忘録-)に合わせたコードなので、単に投稿ページのメニューから current_page_parent を削除したいだけなら、下記のコードだけで大丈夫なはずです。(検証不十分。。
function mypace_custom_navi_menu( $classes, $item ) { global $wp_query; $page_for_posts = get_option( 'page_for_posts' ); $post_type_query = $wp_query->query_vars['post_type']; $del_flag = true; if ( is_singular( 'post' ) || is_category() || is_tag() ) { $del_flag = false; } elseif ( ( is_author() || is_date() || is_author() ) ) { if ( in_array( $post_type_query, array ( '', 'post' ) ) ) { $del_flag = false; } } elseif ( is_tax() ) { $taxonomy = get_taxonomy( $wp_query->query_vars['taxonomy'] ); if ( count( $taxonomy->object_type ) == 1 && $taxonomy->object_type[0] == 'post' ) { $del_flag = false; } } if ( $del_flag && is_numeric( $page_for_posts ) && $item->object_id == $page_for_posts && $item->object == 'page' && $key = array_search( 'current_page_parent', $classes ) ) { unset( $classes[$key] ); } return $classes; } add_filter( 'nav_menu_css_class', 'mypace_custom_navi_menu', 10, 2 );