Comment créer des liens de menu par programmation?

14

J'ai besoin d'ajouter des liens vers le menu existant (ou vers un nouveau) par programme dans Drupal 8.

skorzh
la source

Réponses:

24

Afin de créer automatiquement un élément de menu, celui-ci peut être placé dans un hook_update_Nfichier mymodule.installet s'exécutera lorsque la base de données sera mise à jour (/update.php):

use Drupal\menu_link_content\Entity\MenuLinkContent;
$items = array(
  '1' => 'Menuitem 1',
  '2' => 'Menuitem 2',
  '3' => 'Menuitem 3'
);

foreach($items as $nid => $title) {
  $menu_link = MenuLinkContent::create([
    'title' => $title,
    'link' => ['uri' => 'internal:/node/' . $nid],
    'menu_name' => 'main',
    'expanded' => TRUE,
  ]);
  $menu_link->save();
}

Vous pouvez également créer un menu complet par programmation:

\Drupal::entityTypeManager()
  ->getStorage('menu')
  ->create([
    'id' => 'menu_test',
    'label' => 'Test menu',
    'description' => 'Description text',
  ])
  ->save();
skorzh
la source
1
entity_create est obsolète. Use \ Drupal :: entityTypeManager () -> get storage ('menu') - create ([]);
Eyal
1
Je pense que la bonne solution devrait utiliser le menu yamls
Eyal
3
dans quel crochet est-ce utilisé correctement?
Paul
11
Serait-il possible d'élargir la réponse? Il ne précise pas où ce code peut être placé pour générer les éléments de menu. Je pense que des gens comme moi auront du mal à prendre cela et à le mettre en œuvre efficacement.
cwiggo
6
Comment ajouter un lien de menu enfant à un lien parent?
Matt
8

Si vous souhaitez créer des liens de menu définis par module, ajoutez quelque chose comme cet exemple à votre fichier custom_module.links.menu.yml :

custom_module.admin_item_1:
  title: 'New Admin Item 1'
  parent: system.admin
  description: 'Description of link goes here.'
  route_name: view.some_view_id.page_1

parent(facultatif) est la idcolonne du parent dans le menu_treetableau, et route_nameest l'ID de route interne de Drupal pour l'endroit où vous souhaitez que l'élément de menu soit lié. C'est dans le menu_treetableau comme route_name.

Voir Fournir des liens de menu définis par module et Ajouter un lien de menu pour plus de détails et d'options.

colan
la source
3
Les yamls de menu ne sont utiles que si vous savez à l'avance les éléments de menu que vous souhaitez créer, la création programmatique peut se faire lors de l'enregistrement du nœud.
Duncanmoo
1
Comment ajouter un élément de menu traduisible de cette façon? Comme un élément de menu, mais en 3 langues (différents titres et chemins des éléments de menu).
MilanG
1

Pour développer la réponse @skorzh et répondre au commentaire de @Matt, si vous souhaitez imbriquer un élément de menu dans un autre, vous devez obtenir l'ID parent et le définir comme «parent». À titre d'exemple, ce code imbrique l'élément à l'intérieur du niveau supérieur à l'aide de la variable $top_levelci-dessous.

  $my_menu = \Drupal::entityTypeManager()->getStorage('menu_link_content')
    ->loadByProperties(['menu_name' => 'my-menu-name']);
  foreach ($my_menu as $menu_item) {
    $parent_id = $menu_item->getParentId();
    if (!empty($parent_id) {
      $top_level = $parent_id;
      break;
    }
  }
  $menu_link = MenuLinkContent::create([
    'title' => 'My menu link title',
    'link' => ['uri' => 'internal:/my/path'],
    'menu_name' => 'my-menu-name',
    'parent' => $top_level,
    'expanded' => TRUE,
    'weight' => 0,
  ]);
  $menu_link->save();
wranvaud
la source