web-dev-qa-db-fra.com

Comment afficher les sous-menus sur la page en se référant au parent de niveau supérieur?

J'essaie d'afficher un menu secondaire sur des pages qui affiche toutes les sous-pages de coordination de l'élément de menu principal auquel elles ont accédé, mais mon problème est que certaines pages apparaissent sous plusieurs éléments de menu principaux. Puisque je sais que je ne peux pas attribuer une page à plusieurs parents, existe-t-il un moyen de faire cela avec des champs personnalisés ou des taxonomies peut-être? Ou y a-t-il un meilleur moyen?

Je n’explique probablement pas la meilleure façon, mais vous pouvez voir un exemple de ce que j’essaie de faire sur http://parkered.org . Si vous accédez à Avantages> Industries clés, vous verrez comment l’ensemble du sous-menu Avantages apparaît en haut. Cependant, la page Industries clés existe également sous l'élément de menu Services professionnels. Par conséquent, si vous cliquez dessus, le sous-menu Services professionnels apparaît en haut.

1
CBlanch

Dans votre exemple, la page "Industries clés" apparaît sous une page différente sous chacun de ces menus de niveau supérieur - ou tout au moins, l'URL est différente.

Cela permet très probablement à leur CMS de se différencier et d'utiliser le sous-menu approprié.

Voici ce que je fais quand je veux atteindre cet objectif:

  1. Accrocher dans wp_nav_menu_objects et rechercher un argumentcustomsubmenu, qui contiendra l'ID d'élément de menu parent
  2. Dans ce crochet, désélectionnez les éléments de menu qui n'ont pas le même parent
  3. Ensuite, lorsque vous appelez wp_nav_menu(), fournissez un argument submenu avec l'ID d'élément de menu parent du sous-menu à afficher (je vais expliquer comment procéder ci-dessous).

Connexion à wp_nav_menu_objects et suppression des éléments de menu non enfants:

Voici la fonction que j'utilise pour cela. Il vérifiera l'argument submenu à chaque appel de wp_nav_menu(). Si submenu est défini, il supprimera tout élément qui n'est pas un enfant de l'ID d'élément de menu auquel submenu fait référence:

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;
}

Appel de wp_nav_menu():

Lorsque vous appelez wp_nav_menu(), vous devez ensuite ajouter l'argument personnalisé submenu, par exemple:

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

Bien entendu, la clé est la suivante: comment obtenir cet ID de sous-menu?

Vous pouvez le faire manuellement si vous le souhaitez vraiment, mais un meilleur moyen serait de déterminer automatiquement ce que cet ID devrait être en recherchant la requête en cours.

Essentiellement, vous voulez simplement déterminer l’identifiant de l’élément de menu de la page en cours d’affichage, puis:

  • s'il s'agit d'un élément de menu de niveau supérieur (c'est-à-dire que le parent est 0), envoyez cet ID d'élément de menu à l'argument submenu, ou
  • s'il ne s'agit pas d'un élément de menu de niveau supérieur, envoyez son ID parent à l'argument submenu

Il en résultera alors - tant que cette page ne sera pas utilisée plus d'une fois dans le menu! - dans le sous-menu correct affiché.

Les techniques utilisées varient en fonction de la configuration de votre site et du nombre de "niveaux" de sous-menus que vous souhaitez prendre en charge. Mais cela pourrait ressembler à quelque chose comme ça:

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));

Je dois souligner qu'il s'agit d'une version vraiment simplifiée. vous devrez comprendre comment cela fonctionne plutôt que de simplement le déposer sur votre site. Et vous aurez probablement besoin d'ajouter de la logique supplémentaire pour que le comportement se comporte exactement comme vous le souhaitez sur votre site. Mais j'espère que c'est ce dont vous avez besoin pour commencer!

1
Tim Malone