> For AI agents: the complete documentation index is available at https://docs.halo.run/llms.txt, the full documentation bundle is available at https://docs.halo.run/llms-full.txt.

# 导航菜单

本页 API 自 Halo 2.0.0 起可用。

从 Halo 2.26.0 开始，菜单项通过 `MenuItem.spec.menuName` 归属菜单，并通过 `MenuItem.spec.parent` 记录父级。`menuFinder` 返回的 `menu.menuItems` 已按该关系组成树；请通过每个节点的 `children` 渲染子菜单，不要读取已弃用的 `Menu.spec.menuItems` 或 `MenuItem.spec.children`。

## getByName(name)

```js
menuFinder.getByName(name);
```

### 描述

根据 `metadata.name` 获取菜单。

### 参数

1. `name:string` - 菜单的唯一标识 `metadata.name`。

### 返回值

[#MenuVo](#menuvo)

### 示例

```html
<div th:with="menu = ${menuFinder.getByName('menu-foo')}">
  <ul th:with="menuItems = ${menu.menuItems}">
    <li th:each="menuItem : ${menuItems}">
      <a
        th:href="@{${menuItem.status.href}}"
        th:text="${menuItem.status.displayName}"
        th:target="${menuItem.spec.target?.value}"
      >
      </a>
    </li>
  </ul>
</div>
```

## getPrimary()

```js
menuFinder.getPrimary();
```

### 描述

获取主菜单。

### 参数

无

### 返回值

[#MenuVo](#menuvo)

### 示例

```html
<nav th:with="menu = ${menuFinder.getPrimary()}">
  <th:block
    th:replace="~{modules/menu-tree :: tree(menuItems=${menu.menuItems})}"
  ></th:block>
</nav>
```

```html title="/templates/modules/menu-tree.html"
<ul th:fragment="tree (menuItems)">
  <li th:each="menuItem : ${menuItems}">
    <a
      th:href="@{${menuItem.status.href}}"
      th:text="${menuItem.status.displayName}"
      th:target="${menuItem.spec.target?.value}"
    ></a>
    <th:block th:if="${not #lists.isEmpty(menuItem.children)}">
      <th:block
        th:replace="~{modules/menu-tree :: tree(menuItems=${menuItem.children})}"
      ></th:block>
    </th:block>
  </li>
</ul>
```

## 类型定义

### MenuVo

```jsonc title="MenuVo"
{
  "metadata": {
    "name": "string", // 唯一标识
    "labels": {
      "additionalProp1": "string",
    },
    "annotations": {
      "additionalProp1": "string",
    },
    "creationTimestamp": "2022-11-20T14:44:58.984Z", // 创建时间
  },
  "spec": {
    "displayName": "string", // 显示名称
    "menuItems": [
      // 自 Halo 2.26.0 起已弃用，请使用 MenuItem.spec.menuName 和 MenuItem.spec.parent
      "string",
    ],
  },
  "menuItems": "List<#MenuItemVo>", // menuFinder 根据当前层级关系构建的根菜单项集合
}
```

### MenuItemVo

```jsonc title="MenuItemVo"
{
  "metadata": {
    "name": "string", // 唯一标识
    "labels": {
      "additionalProp1": "string",
    },
    "annotations": {
      "additionalProp1": "string",
    },
    "creationTimestamp": "2022-11-20T14:44:58.984Z", // 创建时间
  },
  "spec": {
    "displayName": "string", // 显示名称，但是不要直接使用这个字段进行显示，最终字段为 status.displayName
    "href": "string", // 链接，同样不要直接使用这个字段，最终字段为 status.href
    "priority": 0, // 排序字段
    "menuName": "string", // 所属菜单的 metadata.name，自 Halo 2.26.0 起作为菜单归属依据
    "parent": "string", // 父菜单项的 metadata.name，根菜单项为空
    "children": [
      // 自 Halo 2.26.0 起已弃用，请使用 spec.parent 表示层级
      "string",
    ],
    "target": "#Target", // 菜单页面打开方式，枚举类型
    "targetRef": {
      // 与其他资源比如文章的关联，一般无需直接使用
      "group": "string",
      "version": "string",
      "kind": "string",
      "name": "string",
    },
  },
  "status": {
    "displayName": "string", // 显示名称
    "href": "string", // 链接
  },
  "children": "List<#MenuItemVo>", // menuFinder 根据 spec.parent 构建的直接子菜单项
  "parentName": "string", // spec.parent 的值
}
```

```java title="Target"
enum Target {
    BLANK("_blank"),                                     // 在新窗口打开
    SELF("_self"),                                       // 在当前窗口打开
    PARENT("_parent"),                                   // 在父窗口打开
    TOP("_top");                                         // 在顶级窗口打开
}
```
