web-dev-qa-db-ja.com

プログラムでメニューリンクを作成するにはどうすればよいですか?

Drupal 8.)で、既存のメニュー(または新しいメニュー)へのリンクをプログラムで追加する必要があります。

14
skorzh

メニュー項目を自動的に作成するには、これを hook_update_N ファイルmymodule.installそして、データベースが更新されたときに実行されます(/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();
}

プログラムでメニュー全体を作成することもできます。

\Drupal::entityTypeManager()
  ->getStorage('menu')
  ->create([
    'id' => 'menu_test',
    'label' => 'Test menu',
    'description' => 'Description text',
  ])
  ->save();
24
skorzh

モジュール定義のメニューリンクを作成する場合は、次の例のようなものを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(オプション)はmenu_treeテーブル内の親のid列であり、route_nameはメニュー項目を配置する場所のDrupalの内部ルートIDですリンクする。 menu_treeテーブルにはroute_nameとして含まれています。

詳細とオプションについては、 モジュール定義のメニューリンクの提供 および メニューリンクの追加 を参照してください。

8
colan

@skorzhの回答を展開し、@ Mattからのコメントに返信するには、メニュー項目を別の項目内にネストする場合は、親IDを取得して「親」として設定する必要があります。例として、このコードは以下の変数$top_levelを使用して、アイテムをトップレベル内にネストします。

  $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();
1
wranvaud