web-dev-qa-db-fra.com

Comment transformer une arborescence de menus en un tableau associatif?

J'ai creusé dans Drupal noyau de menu pour trouver un moyen de construire un tableau associatif à partir d'une arborescence de menu (par exemple, le menu du compte) afin que je puisse sortir les données au format json. Mais il ne semble pas possible de le faire avec Drupal 8. Les informations dont j'ai besoin dans une arborescence de menu incluent le titre, la description, l'url, et j'ai également besoin de savoir s'il a un sous-menu et s'il est activé . Tout cela peut être facilement réalisé en utilisant la fonction menu_build_tree() dans Drupal 7. Veuillez comprendre que j'ai essayé le soi-disant Drupal 8 équivalent de menu_build_tree() (\Drupal::menuTree();) mais cela me donne juste un gros objet à l'aide duquel je ne sais pas comment extraire les données dont j'ai besoin.

7
jiaxin

Vous pouvez charger l'arborescence des menus avec MenuLinkTree::load , qui vous donnera un tableau de liens de menu avec lesquels travailler. À partir de là, il suffit de parcourir et d'obtenir ce dont vous avez besoin, par exemple.

$tree = \Drupal::menuTree()->load('main', new \Drupal\Core\Menu\MenuTreeParameters());
foreach ($tree as $item) {
  $title = $item->link->getTitle();
  $url_obj = $item->link->getUrlObject();
  $has_children = $item->hasChildren;
  // etc...
}

Le link est un MenuLinkInterface , chaque élément lui-même est un MenuLinkTreeElement .

Il serait préférable d'injecter le menu.link_tree service si possible, plutôt que de l'obtenir auprès de \Drupal.

12
Clive

Je suis assez en retard, mais peut-être aide quelqu'un à chercher des réponses, voici ma solution pour générer un tableau récursif à partir des éléments de menu.

private function generateSubMenuTree(&$output, &$input, $parent = FALSE) {
$input = array_values($input);
foreach($input as $key => $item) {
  //If menu element disabled skip this branch
  if ($item->link->isEnabled()) {
    $key = 'submenu-' . $key;
    $name = $item->link->getTitle();
    $url = $item->link->getUrlObject();
    $url_string = $url->toString();

    //If not root element, add as child
    if ($parent === FALSE) {
      $output[$key] = [
        'name' => $name,
        'tid' => $key,
        'url_str' => $url_string
      ];
    } else {
      $parent = 'submenu-' . $parent;
      $output['child'][$key] = [
        'name' => $name,
        'tid' => $key,
        'url_str' => $url_string
      ];
    }

    if ($item->hasChildren) {
      if ($item->depth == 1) {
        $this->generateSubMenuTree($output[$key], $item->subtree, $key);
      } else {
        $this->generateSubMenuTree($output['child'][$key], $item->subtree, $key);
      }
    }
  }
}

Et appelez cette fonction avec

//Get drupal menu
$sub_nav = \Drupal::menuTree()->load('sub-navigation', new \Drupal\Core\Menu\MenuTreeParameters());
//Generate array
$this->generateSubMenuTree($menu_tree2, $sub_nav);
7
Siim