web-dev-qa-db-fra.com

Ajouter la classe CSS du menu de navigation au corps

J'aimerais ajouter la classe CSS de l'élément de menu actuel (et les classes de ses parents et de ses ancêtres) aux classes actuelles du corps de la page.

Par exemple, si l'élément de menu actuel a une classe CSS "produits" (telle que définie dans Apparence | Menus), le corps de la page correspondante doit également avoir la classe "produits".

Si cela a du sens pour quiconque, des idées pour le faire?

J'ai regardé " Comment ajouter des ID d'élément de menu actuels, parents et ancêtres à body_class ()? ", mais impossible d'obtenir ces idées travaille dans mon cas.

2
dvd3141

C'est ce que j'ai réussi à concocter grâce aux conseils de Mridul Aggarwal:

function pa_assign_menu_class_to_body(){
  // 'main' is the theme_location, set earlier using register_nav_menus()
  $menu_name = 'main';
  $class_list = array();

  if ( ( $locations = get_nav_menu_locations() ) && isset( $locations[ $menu_name ] ) ) {
    $menu = wp_get_nav_menu_object( $locations[ $menu_name ] );
    $menu_items = wp_get_nav_menu_items($menu->term_id);

    // _wp_menu_item_classes_by_context() adds current, current_item_parent and current_item_ancestor to the appropriate arrays in the provided variable
    _wp_menu_item_classes_by_context( $menu_items );

    $classes = array();

    foreach($menu_items as $menu_item) {
      if ($menu_item->current == 1) {
        $classes['current'] = $menu_item->classes;
      }
      if ($menu_item->current_item_parent == 1) {
        $classes['parents'] = $menu_item->classes;
      }
      if ($menu_item->current_item_ancestor == 1) {
        $classes['ancestors'] = $menu_item->classes;
      }
    }

    // create a one-dimensional array of unique classes
    foreach($classes as $class) 
      foreach ($class as $cls) $class_list[] = $cls;
    $class_list = array_values(array_unique($class_list));
  }
  // if, for some reason, we have no results, we need to assign a default class otherwise WordPress complains
  if (empty($class_list)) $class_list[] = 'default';
  return $class_list;
}
add_filter( 'body_class', 'pa_assign_menu_class_to_body');

Cette fonction fait aussi un peu , car elle ajoute toutes les classes de type menu-item-. Tout ce que je veux vraiment, ce sont les classes CSS personnalisées que l'utilisateur a entrées dans le champ Classes CSS de l'écran d'administration des menus WordPress. Toute idée sur la manière d'extraire uniquement ces classes serait la bienvenue.

1
dvd3141

Légère modification de votre code affiché ci-dessus pour obtenir uniquement la classe personnalisée. La classe personnalisée est toujours le premier élément.

function pa_assign_menu_class_to_body(){
  // 'main' is the theme_location, set earlier using register_nav_menus()
  $menu_name = 'main';
  $class_list = array();

  if ( ( $locations = get_nav_menu_locations() ) && isset( $locations[ $menu_name ] ) ) {
    $menu = wp_get_nav_menu_object( $locations[ $menu_name ] );
    $menu_items = wp_get_nav_menu_items($menu->term_id);

    // _wp_menu_item_classes_by_context() adds current, current_item_parent and current_item_ancestor to the appropriate arrays in the provided variable
    _wp_menu_item_classes_by_context( $menu_items );

    $classes = array();

    foreach($menu_items as $menu_item) {
      if ($menu_item->current == 1) {
        $classes['current'] = $menu_item->classes;
      }
      if ($menu_item->current_item_parent == 1) {
        $classes['parents'] = $menu_item->classes;
      }
      if ($menu_item->current_item_ancestor == 1) {
        $classes['ancestors'] = $menu_item->classes;
      }
    }

    // create a one-dimensional array of unique classes
    foreach($classes as $class) 
      foreach ($class as $cls) $class_list[] = $cls;
    $class_list = array_values(array_unique($class_list));
  }
  // if, for some reason, we have no results, we need to assign a default class otherwise WordPress complains
  if (empty($class_list)) $class_list[] = 'default';
  //Gets first class if custom. If not, returns null.
  if ($class_list[0] != 'menu-item') {
      $class_list_return[] = $class_list[0];
  } else {
      $class_list_return[] = null;
  }
  return $class_list_return;
}
add_filter( 'body_class', 'pa_assign_menu_class_to_body');

EDIT: Ce filtre et le filtre d'origine remplacent toutefois les classes par défaut. Si vous voulez juste les ajouter ...

function pa_assign_menu_class_to_body($classes){
  // 'main' is the theme_location, set earlier using register_nav_menus()
  $menu_name = 'main';
  $class_list = array();

  if ( ( $locations = get_nav_menu_locations() ) && isset( $locations[ $menu_name ] ) ) {
    $menu = wp_get_nav_menu_object( $locations[ $menu_name ] );
    $menu_items = wp_get_nav_menu_items($menu->term_id);

    // _wp_menu_item_classes_by_context() adds current, current_item_parent and current_item_ancestor to the appropriate arrays in the provided variable
    _wp_menu_item_classes_by_context( $menu_items );

    foreach($menu_items as $menu_item) {
      if ($menu_item->current == 1) {
        $classes['current'] = $menu_item->classes;
      }
      if ($menu_item->current_item_parent == 1) {
        $classes['parents'] = $menu_item->classes;
      }
      if ($menu_item->current_item_ancestor == 1) {
        $classes['ancestors'] = $menu_item->classes;
      }
    }

    // create a one-dimensional array of unique classes
    foreach($classes as $class) 
      foreach ($class as $cls) $class_list[] = $cls;
    $class_list = array_values(array_unique($class_list));
  }
  // if, for some reason, we have no results, we need to assign a default class otherwise WordPress complains
  if (empty($class_list)) $class_list[] = 'default';
  //Gets first class if custom. If not, returns null.
  if ($class_list[0] != 'menu-item') {
      $class_list_return[] = $class_list[0];
  } else {
      $class_list_return[] = null;
  }
  return array_merge($classes, $class_list_return);
}
add_filter( 'body_class', 'pa_assign_menu_class_to_body');
0
Dadiocoleman

Dans la réponse you linked , faites une var_dump($dosmenu); juste au-dessus de la ligne _wp_menu_item_classes_by_context( $dosmenu );. Cette variable doit déjà être initialisée avec les classes souhaitées.

Après cela, vous pouvez adapter la boucle foreach en conséquence et utiliser cette fonction en tant que filtre pour body_class.

Les classes définies dans l’administrateur sont stockées en tant que méta-publications avec la clé _menu_item_classes qui sont automatiquement initialisées dans l’appel à wp_get_nav_menu_items

0
Mridul Aggarwal