web-dev-qa-db-ja.com

トップレベルの親を参照してページにサブメニューを表示する方法

そこから移動したトップレベルメニュー項目のすべての調整サブページを表示するセカンダリメニューをページに表示しようとしていますが、いくつかのページが複数のトップレベルメニュー項目の下に表示されるという問題があります。ページを複数の保護者に割り当てることはできないことがわかっているので、カスタムフィールドまたは分類法を使用してこれを行う方法はありますか?それとももっと良い方法はありますか?

私はおそらくこれを最善の方法では説明していませんが、私が達成しようとしていることの例を見ることができます http://parkered.org [アドバンテージ]> [主要産業]に移動すると、上部に[アドバンテージ]サブメニュー全体がどのように表示されるかがわかります。ただし、[主要サービス]ページも[ビジネスサービス]メニュー項目の下にあるため、そこからクリックすると、代わりに[ビジネスサービス]サブメニューが上部に表示されます。

1
CBlanch

あなたの例では、 '主要産業'ページはそれらのトップレベルメニューのそれぞれの下で異なるページであるように見えます - あるいは、少なくとも、URLは異なります。

これはおそらく彼らのCMSが区別して正しいサブメニューを使用することを可能にします。

これを達成したいときは、次のようにします。

  1. wp_nav_menu_objectsにフックして、親メニュー項目IDを保持するカスタムsubmenu引数を確認します。
  2. そのフック内で、同じ親を持たないメニュー項目を設定解除します。
  3. 次に、wp_nav_menu()を呼び出すときに、表示するサブメニューの親メニュー項目IDを指定してsubmenu引数を指定します(これを以下に行う方法について説明します)

wp_nav_menu_objectsへのフックと子以外のメニュー項目の設定解除:

これが私がこれに使う関数です。 wp_nav_menu()を呼び出すたびにsubmenu引数をチェックします。 submenuが設定されている場合、submenuが参照しているメニュー項目IDの子ではないすべての項目を削除します。

add_filter("wp_nav_menu_objects", "mytheme_submenu_limit", 10, 2);

function mytheme_submenu_limit($items, $args){

    if(empty($args->submenu)){ return $items; } // if no submenu arg is set, return immediately

    $filtered = wp_filter_object_list($items, array("ID" => $args->submenu), "and", "ID");
    $parent_id = array_pop($filtered);
    $children = mytheme_submenu_get_children_ids($parent_id, $items);

    foreach($items as $key => $item){
        if(!in_array($item->ID, $children)){
            unset($items[$key]);
        }
    }

    return $items;

}

function my_theme_submenu_get_children_ids($id, $items){
    $ids = wp_filter_object_list($items, array("menu_item_parent" => $id), "and", "ID");
    foreach($ids as $id){ $ids = array_merge($ids, submenu_get_children_ids($id, $items)); }
    return $ids;
}

wp_nav_menu()を呼び出す:

wp_nav_menu()を呼び出すときは、次にカスタムのsubmenu引数を追加する必要があります。

wp_nav_menu(array("theme_location" => "my_menu_area", "submenu" => 240));

もちろん、ここで鍵となるのは - そのサブメニューIDをどのように取得するのですか?

必要に応じてこれを手動で行うことができますが、より良い方法は現在のクエリを通していくつかの狩りをすることによってこのIDがどうあるべきかを自動的に決定することでしょう。

基本的には、現在表示されているページのメニュー項目IDが何であるかを確認したいだけです。

  • それがトップレベルのメニュー項目である場合(つまり、親が0の場合)、そのメニュー項目IDをsubmenu引数に送信する。
  • それがトップレベルのメニュー項目ではない場合、その親IDをsubmenu引数に送ります。

その結果、そのページがメニュー内で2回以上使用されていない限り、その結果になります。 - 表示されている正しいサブメニュー内。

このためのテクニックはあなたのサイトの設定、そして、決定的に、あなたがサポートしたいサブメニューのいくつの「レベル」によって変わるでしょう。しかし、これは次のようになります。

global $wp_query;
$queried_object = $wp_query->get_queried_object();
$menu_query_args = array("meta_query" => array("key" => "_menu_item_object_id", "value" => $queried_object->ID));

$locations = get_nav_menu_locations();
$menu_objects = wp_get_nav_menu_items($locations["my_menu_area"], $menu_query_args);

if($menu_objects[0]->menu_item_parent == 0){ $submenu_id = $menu_objects[0]->ID; }
else{ $submenu_id = $menu_objects[0]->menu_item_parent; }

wp_nav_menu(array("theme_location" => "my_menu_area", "submenu" => $submenu_id));

私はこれが本当に単純化されたバージョンであることを強調しなければなりません。あなたはそれをあなたのサイトに単に落とすよりもむしろそれがどのように働くかを理解する必要があるでしょう。そして、あなたはおそらくそれがあなたがあなたのサイトであなたが望むように正確に振る舞うように追加のロジックを追加する必要があるでしょう。しかし、うまくいけば、これはあなたが始めるために必要なものです!

1
Tim Malone