wp_nav_menu()祖先のクラスを強調表示します。
-
16-10-2019 - |
質問
(モデレーター注: もともと「ナビゲーション構造の子供のないWP_NAV_MENUの祖先クラス」というタイトル
私は持っています wp_nav_menu
私のヘッダーには3ページが入っていました。私がそれらのページの1つにいるとき、 li
メニューにそのページを含めると、クラスが取得されます .current_page_item
. 。これらの3ページにはテンプレートがあり、これらのテンプレートには、特定のコンテンツタイプのすべての投稿を取得するためのカスタムクエリが含まれています。実際には、知覚されました "子供" このトップレベルのページは実際には子供ではなく、テンプレートを使用してそのトップレベルページに関連付けられているコンテンツタイプにすぎません。
トップレベルのメニュー項目を取得したい 'current-ancestor'
クラスユーザーが特定の投稿タイプの単一ページをブラウジングしている場合、このページにはテンプレートファイルのカスタムクエリのみでそのページに関連付けられています。
それが理にかなっていることを願っています - そうでない場合は、私があなたを失った場所を教えてください!どんな助けにも感謝しています。
- 詳細のために編集:たとえば、呼ばれる静的ページがあります ワークショップ それはテンプレートを使用しています。そのナメクジはそうです ワークショップ. 。テンプレートにはカスタムget_posts関数とその中にループがあり、呼ばれるカスタムコンテンツタイプのすべての投稿をプルして表示します ワークショップ. 。これらのワークショップのタイトルのいずれかをクリックすると、そのコンテンツの完全なコンテンツに取り込まれます。カスタムポストタイプのパーマリンク構造は、ワークショップに設定されています/投稿名, 、したがって、ユーザーが見ているように、これらのコンテンツはワークショップページの子供です。実際には、それらはすべて1つのコンテンツタイプですが、ページとは関係ありません。メニューを効果的に閉じる必要があるのはそのギャップであり、「ワークショップ」のコンテンツを閲覧するときに「ワークショップ」メニュー項目を強調しています。
繰り返しますが、それが理にかなっていることを願っています、私は1つの段落で20回以上「ワークショップ」と言ったと思います!
解決
より簡単な解決策があります。各投稿タイプのページの作成を忘れて、NAVアイテムを作成できるようにしてください。学んだように、WPには閲覧しているカスタムタイプがそのページに関連していることを認識する方法がないからです。
代わりに、外観 - >メニューでカスタムリンクを作成します。カスタムタイプを返してラベルを付けるURLを配置してから、「メニューに追加」を押します。
http://example.com/workshops/
または非プレイペルマリンク:
http://example.com/?post_type=workshops
これだけで、そのカスタム投稿タイプですべての投稿を表示するNAVボタンを作成するだけで、そのNAVアイテムをクリックしたときに現在のメニューアイテムクラスも追加されますが、まだNAVクラスを追加していません。これ以外のURL
次に、作成したら、その新しいアイテムの構成に移動し、「タイトル属性」フィールドにカスタム投稿タイプのスラグを入力します(説明フィールドも使用できますが、それは管理画面オプションに隠されています。デフォルト)。
今、あなたはフックする必要があります nav_menu_css_class
フィルター(各NAVアイテムに起動されます)と表示されているコンテンツがカスタムNAVアイテムに示されているポストタイプのものであるかどうかを確認します。
add_filter('nav_menu_css_class', 'current_type_nav_class', 10, 2 );
function current_type_nav_class($classes, $item) {
$post_type = get_query_var('post_type');
if ($item->attr_title != '' && $item->attr_title == $post_type) {
array_push($classes, 'current-menu-item');
};
return $classes;
}
この場合、タイトル属性のフィールドコンテンツが空ではないこと、およびそれらが現在のpost_typeが照会されているかどうかを確認します。その場合、現在のメニューアイテムクラスをクラス配列に追加し、変更された配列を返します。
これを変更するように変更できますが、NAVアイテムのタイトルを単純に一致させることができますが、何らかの理由でNAVアイテムにポストタイプのプレーンラグとは異なる方法でタイトルを付けたい場合は、タイトル属性または説明フィールドを使用すると、その柔軟性が得られます。
NAVメニュー項目に一致する投稿タイプの単一のアイテム(またはおそらくアーカイブリスト)を表示するときはいつでも、そのアイテムにはCSSクラスのCurrent-Menu-Itemが与えられるので、ハイライトが機能します。
ページやページのテンプレートは必要ありません;-) URLクエリが適切な投稿を取得することを処理します。ループテンプレートは、クエリ出力の表示に対応します。この関数は、表示されているものを認識し、CSSクラスを追加します。
ボーナス
使用してプロセスを自動化することもできます wp_update_nav_menu_item
, 、すべての投稿タイプに対して自動的にメニュー項目を生成することにより。この例では、最初に取得する必要があります $menu_id
このアイテムを追加するNAVメニューの。
$types = get_post_types( array( 'exclude_from_search' => false, '_builtin' => false ), 'objects' );
foreach ($types as $type) {
wp_update_nav_menu_item( $menu_id, 0, array(
'menu-item-type' => 'custom',
'menu-item-title' => $type->labels->name,
'menu-item-url' => get_bloginfo('url') . '/?post_type=' . $type->rewrite['slug'],
'menu-item-attr-title' => $type->rewrite['slug'],
'menu-item-status' => 'publish'
)
);
}
他のヒント
使用する代わりに
$ post_type = get_query_var( 'post_type');
あなたは試してみたいかもしれません:
$ post_type = get_post_type();
Somtimesのように、投稿タイプはクエリvarに設定されていません。これは、「投稿」のデフォルトのpost_typeの場合です。したがって、リストページからリストされている投稿を強調表示する場合は、これを使用する必要があります。 get_very_var()は、カスタムではない投稿タイプの空の文字列を返すだけです。
add_filter('nav_menu_css_class', 'current_type_nav_class', 10, 2 );
function current_type_nav_class($classes, $item) {
$post_type = get_post_type();
if ($item->attr_title != '' && $item->attr_title == $post_type) {
array_push($classes, 'current-menu-item');
};
return $classes;
}
@somatic-それは空想です!コードを少し変更したので、特定の分類法(関連するpost_typeのみを使用している)にも機能します。アイデアは、メニュー項目のタイトル属性を使用して、POST_TYPEの名前と分類法の名前の両方を保存し、セミコロンで区切り、関数によって爆発することです。
add_filter('nav_menu_css_class', 'current_type_nav_class', 10, 2 );
function current_type_nav_class($classes, $item) {
# get Query Vars
$post_type = get_query_var('post_type');
$taxonomy = get_query_var('taxonomy');
# get and parse Title attribute of Menu item
$title = $item->attr_title; // menu item Title attribute, as post_type;taxonomy
$title_array = explode(";", $title);
$title_posttype = $title_array[0];
$title_taxonomy = $title_array[1];
# add class if needed
if ($title != '' && ($title_posttype == $post_type || $title_taxonomy == $taxonomy)) {
array_push($classes, 'current-menu-item');
};
return $classes;
}
wp_list_pagesで作業したい場合は、ここで私の解決策。
これをfunctions.phpに追加します
add_filter('page_css_class', 'my_page_css_class', 10, 2);
function my_page_css_class($css_class, $page){
$post_type = get_post_type();
if($post_type != "page"){
$parent_page = get_option('page_for_custom_post_type-'.$post_type);
if($page->ID == $parent_page)
$css_class[] = 'current_page_parent';
}
return $css_class;
}
ここで、wp_optionsテーブルに新しい行を追加します option_name の page_for_custom_post_type-xxxx そしてa option_value とともに Page-ID あなたは接続したいです。
おそらく、あなたはすでに呼ばれるオプションがあることを認識しました page_for_posts. 。 uが1つのカスタム投稿タイプのみを持っている場合、uはドロップダウンで/wp-admin/options-reading.phpでページを設定でき、ナビゲーションはcurrent_pageを正しく設定します。
WordPressコアは、登録されているすべてのポストタイプのドロップダウンでこのセクションを拡張する必要があると思います。
ページに固執し、ページテンプレート名をNAVアイテムのクラスとして使用することにしました。これにより、他のソリューションのいくつかについて気に入らなかったタイトル属性を乱雑にすることを避けることができます。
add_filter('nav_menu_css_class', 'mbudm_add_page_type_to_menu', 10, 2 );
//If a menu item is a page then add the template name to it as a css class
function mbudm_add_page_type_to_menu($classes, $item) {
if($item->object == 'page'){
$template_name = get_post_meta( $item->object_id, '_wp_page_template', true );
$new_class =str_replace(".php","",$template_name);
array_push($classes, $new_class);
return $classes;
}
}
また、header.phpにボディクラスが追加されています
<body <?php body_class(); ?>>
最後に、このソリューションでは、選択した/アクティブ状態をNAVメニュー項目に適用するためにいくつかの追加のCSSが必要です。このページの子供としてページに関連する分類アーカイブとカスタム投稿タイプを表示するために使用します。
/* selected states - include sub pages for anything related to products */
#nav-main li.current-menu-item a,
body.single-mbudm_product #nav-main li.lp_products a,
body.tax-mbudm_product_category #nav-main li.lp_products a,
#nav-main li.current_page_parent a{color:#c00;}
@somatic-素晴らしいコード!私は自分で1つの変更をしました。目的の目的のためにタイトル属性を維持したかったので、代わりに、画面オプションで有効にできるリンク関係(XFN)の高度なメニュープロパティにカスタムポストタイプのスラグを配置しました。私は修正しました
if ($item->attr_title != '' && $item->attr_title == $post_type) {
そしてそれを変更しました
if ($item->xfn != '' && $item->xfn == $post_type) {
いい仕事体細胞。
残念ながら、私はあなたが説明した方法でページにカスタム投稿タイプをリストする方法を理解していません。 Page-portfolio.phpを使用してページに追加しない場合、取得するのは404ページだけです。
Gavinが好きなら、このようなブログページから「current_page_parent」を削除するために、あなたが少し機能するように変更しました。
add_filter('nav_menu_css_class', 'current_type_nav_class', 10, 2);
function current_type_nav_class($css_class, $item) {
$post_type = get_query_var('post_type');
if (get_post_type()=='portfolio') {
$current_value = "current_page_parent";
$css_class = array_filter($css_class, function ($element) use ($current_value) { return ($element != $current_value); } );
}
if ($item->attr_title != '' && $item->attr_title == $post_type) {
array_push($css_class, 'current_page_parent');
};
return $css_class;
}