umi-labs/menu-plugin
GitHub: umi-labs/menu-plugin
为 Payload CMS v3 提供灵活可配置的菜单管理系统,支持多种链接类型、嵌套下拉、多语言和 REST API 输出,让导航菜单的创建与维护完全在后台完成。
Stars: 2 | Forks: 0
# @foundrykit/menu-plugin
一个 [Payload CMS](https://payloadcms.com) v3 插件,为管理面板添加可配置的菜单管理系统。它允许你对嵌套导航进行建模,按 slug 获取菜单,并在常规前端代码中使用它们,而无需依赖 Payload 管理 UI 上下文。
## 功能
- 多种项类型:internal、external、reference、anchor、mailto、tel、custom
- 具有可配置深度的嵌套下拉菜单
- 针对内部路径、电话号码、锚点和电子邮件链接的管理 URL 字段 UI
- 支持 locale 和 depth 参数的公共 `GET /api/menus/:slug` 端点
- 可选的导入/导出端点,默认仅管理员可访问
- 带有自动失效机制的服务器端菜单缓存
- 对前端安全的 `fetchMenu` 辅助函数以及基于此构建的 `useMenu` Hook
- 每项的可见性、target、rel、roles 和自定义属性
- 使用 `slug + locale` 实现菜单本地化标识
## 安装
```
pnpm add @foundrykit/menu-plugin
```
## 快速开始
```
import { buildConfig } from 'payload'
import { menuPlugin } from '@foundrykit/menu-plugin'
export default buildConfig({
plugins: [
menuPlugin({
baseUrl: 'https://example.com',
relationTo: ['pages', 'posts'],
}),
],
})
```
这将在 Payload 中注册一个 `menus` 集合。
## 配置
| 选项 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| `baseUrl` | `string` | `''` | 在管理面板中为内部链接显示的基础 URL 前缀 |
| `cacheTTL` | `number` | `60000` | 服务器缓存 TTL(以毫秒为单位) |
| `disabled` | `boolean` | `false` | 保留集合 schema,但禁用插件运行时端点、Hook 和管理辅助 UI |
| `enableImportExport` | `boolean` | `true` | 注册导入/导出端点 |
| `maxDepth` | `number` | `2` | 下拉菜单项的最大嵌套深度 |
| `relationTo` | `string \| string[]` | `'pages'` | 可用于 reference 链接的集合 |
| `requireAdminForImportExport` | `boolean` | `true` | 导入/导出端点需要经过身份验证的管理员用户 |
示例:
```
menuPlugin({
baseUrl: 'https://mysite.com',
cacheTTL: 300_000,
maxDepth: 3,
relationTo: ['pages', 'posts', 'products'],
})
```
## 菜单标识与语言环境
菜单由 `slug + locale` 唯一标识。
- `slug: "main-menu", locale: "en"` 和 `slug: "main-menu", locale: "fr"` 可以共存
- locale 值统一转换为小写
- 没有 locale 的菜单将被视为独立的默认变体
## REST API
### 按 slug 获取菜单
```
GET /api/menus/:slug
```
查询参数:
- `locale`:可选的 locale 变体
- `depth`:Payload 关联深度,默认为 `0`
示例:
```
curl 'https://example.com/api/menus/main-menu?locale=en&depth=1'
```
### 导出菜单
```
GET /api/menus-export
```
默认情况下,这需要经过身份验证的管理员用户。
### 导入菜单
```
POST /api/menus-import
Content-Type: application/json
```
接受菜单文档的 JSON 数组或 `{ "menus": [...] }` 格式。
导入时按 `slug + locale` 执行 upsert 操作。
示例响应:
```
{
"created": 1,
"updated": 2,
"errors": []
}
```
## 前端用法
### `fetchMenu`
在任何拥有 fetch 实现的地方使用 `fetchMenu`,包括服务器组件和非 Payload 前端代码。
```
import { fetchMenu } from '@foundrykit/menu-plugin/rsc'
const menu = await fetchMenu({
slug: 'main-menu',
locale: 'en',
depth: 1,
baseURL: 'https://example.com',
})
```
### `useMenu`
```
'use client'
import { useMenu } from '@foundrykit/menu-plugin/client'
export function Navigation() {
const { error, isLoading, menu } = useMenu({
slug: 'main-menu',
locale: 'en',
depth: 1,
baseURL: 'https://example.com',
})
if (isLoading) return
Loading...
if (error) return {error}
if (!menu) return null
return {JSON.stringify(menu, null, 2)}
}
```
`useMenu` 包含 30 秒的客户端缓存,并在组件卸载时中止正在进行的请求。
## 缓存
- 菜单在第一次 GET 请求后被缓存
- 缓存键包括 `slug`、`locale` 和 `depth`
- 缓存条目在创建、更新和删除时失效
- 默认服务器 TTL 为 60 秒,可通过 `cacheTTL` 进行配置
## 环境要求
- Payload CMS v3
- Node.js 18.20.2+ 或 20.9.0+
## 许可证
MIT标签:Admin面板, CMS插件, DNS解析, GNU通用公共许可证, JSON, MITM代理, Node.js, Payload CMS, React Hook, RESTful API, SEO优化, TypeScript, UI组件, 内容管理系统, 前端架构, 后端开发, 多语言支持, 安全插件, 安全测试框架, 导航生成, 开源项目, 提示词优化, 插件开发, 数据缓存, 无头CMS, 网站导航, 网络测绘, 菜单管理, 路由管理