管理面板 API:导航与设置(Navigation & settings)
页面摘要: 在
register中使用addMenuLink添加侧边栏链接。使用addSettingsLink既可创建新的设置板块(将 section 对象作为第一个参数传入),也可扩展已有的设置板块(传入 section id 字符串)。遗留的createSettingSection和addSettingsLinks方法已弃用。
插件可以自定义管理面板的导航侧边栏和设置页面,以便访问其功能。本页描述的所有函数都在你插件入口文件的 register 或 bootstrap 生命周期函数中调用。
在深入阅读本页概念之前,请确保你已经:
- 创建了一个 Strapi 插件,
- 阅读并理解了 Admin Panel API 的基础知识。
导航侧边栏(菜单链接)
导航侧边栏是管理面板左侧的主菜单。插件可以使用 register 生命周期函数中的 addMenuLink() 方法向此侧边栏添加链接。
添加菜单链接
向导航侧边栏添加链接使用 addMenuLink() 函数,应通过插件的 register() 生命周期函数注册。
菜单链接接受以下参数:
| Parameter | Type | Required | Description |
|---|---|---|---|
to | string | ✅ | 链接应指向的路径(相对于管理面板根目录)(见 附加信息) |
icon | React.ElementType | ✅ | 在导航中显示的图标的 React 组件 |
intlLabel | object | ✅ | 链接的标签,遵循 React Int'l 约定,包含: |
id:用于插入本地化标签的 iddefaultMessage:链接的默认标签 | |permissions|Array<Permission>| ✅ | 控制链接可见性的权限对象数组。传入[]表示无限制。 | |Component|function| ❌ | 返回插件主页面组件动态import()的函数。页面模块必须将组件作为default导出。如果省略,则不会注册路由(仅标签条目)。 | |position|number| ❌ | 在菜单中的数字位置(数字越小越靠前) | |licenseOnly|boolean| ❌ | 如果为true,显示一个 ⚡ 图标以表明该功能需要付费许可证(默认:false) | |target|string| ❌ | 标准锚点target属性(例如外部链接的_blank) | |notificationsCount|number| ❌ | 显示在菜单标签旁的徽标计数 | |exact|boolean| ❌ | 活动链接匹配是否应精确匹配 |
intlLabel.id 的值应对应于你位于 admin/src/translations/[locale].json 的翻译文件中的键。详见 管理面板本地化。
permissions 参数仅控制链接在导航中是否可见。它不会保护页面本身。知道 URL 的用户仍可直接访问该页面。要完全保护插件路由,你还必须在页面组件内部检查权限,并在服务器端使用 actionProvider.registerMany 注册你的 RBAC 操作。有关完整演练,请参阅 插件的管理面板权限 指南。
JavaScript
import PluginIcon from './components/PluginIcon';
export default {
register(app) {
// highlight-start
app.addMenuLink({
to: `/plugins/my-plugin`,
icon: PluginIcon,
intlLabel: {
id: 'my-plugin.plugin.name',
defaultMessage: 'My Plugin',
},
Component: () => import('./pages/App'),
permissions: [], // Array of permission objects
position: 3, // Position in the menu (lower numbers appear first)
licenseOnly: false, // Set to true to show ⚡ icon for paid features
});
// highlight-end
app.registerPlugin({
id: 'my-plugin',
name: 'My Plugin',
});
},
};
TypeScript
import PluginIcon from './components/PluginIcon';
import type { StrapiApp } from '@strapi/admin/strapi-admin';
export default {
register(app: StrapiApp) {
// highlight-start
app.addMenuLink({
to: `/plugins/my-plugin`,
icon: PluginIcon,
intlLabel: {
id: 'my-plugin.plugin.name',
defaultMessage: 'My Plugin',
},
Component: () => import('./pages/App'),
permissions: [], // Array of permission objects
position: 3, // Position in the menu (lower numbers appear first)
licenseOnly: false, // Set to true to show ⚡ icon for paid features
});
// highlight-end
app.registerPlugin({
id: 'my-plugin',
name: 'My Plugin',
});
},
};
Component 所引用的页面模块必须将组件作为 默认导出(例如 admin/src/pages/App.tsx 中的 export default App;)。早期版本的 Strapi 接受返回具名导出的 async 回调,但该模式已弃用,并在运行时会记录警告。请使用 Component: () => import(path),以便动态导入直接解析到模块的默认导出。
设置(Settings)
设置 API 允许插件创建新的设置板块或向现有板块添加链接。设置板块是从导航侧边栏中的 Settings 菜单项可访问的配置页面的分组。
创建新的设置板块
要创建新的设置板块,请调用 addSettingsLink(),并将一个 section 对象({ id, intlLabel })作为第一个参数、一个链接对象数组作为第二个参数。这可以在 register 或 bootstrap 生命周期函数中完成:
JavaScript
export default {
register(app) {
// highlight-start
app.addSettingsLink(
{
id: 'my-plugin',
intlLabel: {
id: 'my-plugin.settings.section-label',
defaultMessage: 'My Plugin Settings',
},
},
[
{
intlLabel: {
id: 'my-plugin.settings.general',
defaultMessage: 'General',
},
id: 'general',
to: 'my-plugin/general',
Component: () => import('./pages/Settings/General'),
},
{
intlLabel: {
id: 'my-plugin.settings.advanced',
defaultMessage: 'Advanced',
},
id: 'advanced',
to: 'my-plugin/advanced',
Component: () => import('./pages/Settings/Advanced'),
},
],
);
// highlight-end
app.registerPlugin({
id: 'my-plugin',
name: 'My Plugin',
});
},
};
TypeScript
import type { StrapiApp } from '@strapi/admin/strapi-admin';
export default {
register(app: StrapiApp) {
// highlight-start
app.addSettingsLink(
{
id: 'my-plugin',
intlLabel: {
id: 'my-plugin.settings.section-label',
defaultMessage: 'My Plugin Settings',
},
},
[
{
intlLabel: {
id: 'my-plugin.settings.general',
defaultMessage: 'General',
},
id: 'general',
to: 'my-plugin/general',
Component: () => import('./pages/Settings/General'),
},
{
intlLabel: {
id: 'my-plugin.settings.advanced',
defaultMessage: 'Advanced',
},
id: 'advanced',
to: 'my-plugin/advanced',
Component: () => import('./pages/Settings/Advanced'),
},
],
);
// highlight-end
app.registerPlugin({
id: 'my-plugin',
name: 'My Plugin',
});
},
};
当用于创建新的板块时,addSettingsLink() 接受以下参数:
-
第一个参数是板块配置:
Parameter Type Required Description idstring✅ 设置板块的唯一标识符 intlLabelobject✅ 板块的本地化标签,遵循 React Int'l 约定,包含:
id:用于插入本地化标签的 iddefaultMessage:板块的默认标签 |
-
第二个参数是一个链接对象数组;每个链接对象包含以下内容:
Parameter Type Required Description idstring✅ 设置链接的唯一标识符 tostring✅ 相对于设置路由的路径(不要包含 settings/前缀)(见 附加信息)intlLabelobject✅ 包含 id和defaultMessage的本地化标签对象permissionsArray<Permission>✅ 控制链接可见性的权限对象数组。传入 []表示无限制。Componentfunction❌ 返回设置页面组件动态 import()的函数。页面模块必须将组件作为default导出。如果省略,则不会注册路由(仅标签条目)。positionnumber❌ 在板块内的数字位置(数字越小越靠前) licenseOnlyboolean❌ 如果为 true,显示一个 ⚡ 图标(默认:false)exactboolean❌ 活动链接匹配是否应精确匹配
专用的 app.createSettingSection(section, links) 方法已弃用。它仍然可用(内部委托给 addSettingsLink),但新代码应直接调用 addSettingsLink(section, links)。请参阅 已弃用的方法。
向现有设置板块添加链接
要向现有的设置板块添加链接,请在 bootstrap() 生命周期函数中使用 addSettingsLink(),并将一个 section id 字符串作为第一个参数。第二个参数可以是单个链接对象,也可以是链接对象数组。这两种形式都被同一方法支持。
JavaScript
export default {
register(app) {
app.registerPlugin({
id: 'my-plugin',
name: 'My Plugin',
});
},
bootstrap(app) {
// Add a single link to the global settings section
// highlight-start
app.addSettingsLink('global', {
intlLabel: {
id: 'my-plugin.settings.documentation',
defaultMessage: 'Documentation',
},
id: 'documentation',
to: 'my-plugin/documentation',
Component: () => import('./pages/Settings/Documentation'),
permissions: [],
licenseOnly: false,
});
// highlight-end
// Add multiple links at once to the global settings section
// highlight-start
app.addSettingsLink('global', [
{
intlLabel: {
id: 'my-plugin.settings.general',
defaultMessage: 'General',
},
id: 'general',
to: 'my-plugin/general',
Component: () => import('./pages/Settings/General'),
},
{
intlLabel: {
id: 'my-plugin.settings.advanced',
defaultMessage: 'Advanced',
},
id: 'advanced',
to: 'my-plugin/advanced',
Component: () => import('./pages/Settings/Advanced'),
},
]);
// highlight-end
},
};
TypeScript
import type { StrapiApp } from '@strapi/admin/strapi-admin';
export default {
register(app: StrapiApp) {
app.registerPlugin({
id: 'my-plugin',
name: 'My Plugin',
});
},
bootstrap(app: StrapiApp) {
// Add a single link to the global settings section
// highlight-start
app.addSettingsLink('global', {
intlLabel: {
id: 'my-plugin.settings.documentation',
defaultMessage: 'Documentation',
},
id: 'documentation',
to: 'my-plugin/documentation',
Component: () => import('./pages/Settings/Documentation'),
permissions: [],
licenseOnly: false,
});
// highlight-end
// Add multiple links at once to the global settings section
// highlight-start
app.addSettingsLink('global', [
{
intlLabel: {
id: 'my-plugin.settings.general',
defaultMessage: 'General',
},
id: 'general',
to: 'my-plugin/general',
Component: () => import('./pages/Settings/General'),
},
{
intlLabel: {
id: 'my-plugin.settings.advanced',
defaultMessage: 'Advanced',
},
id: 'advanced',
to: 'my-plugin/advanced',
Component: () => import('./pages/Settings/Advanced'),
},
]);
// highlight-end
},
};
addSettingsLink 以 sectionId 字符串作为第一个参数(例如 'global' 或 'permissions')。第二个参数是单个链接对象或链接对象数组,使用与 创建新的设置板块 中 links 数组相同的属性。
复数形式的 app.addSettingsLinks(sectionId, links) 方法已弃用。请改用 addSettingsLink(sectionId, links)(单数)并传入数组;它同时接受单个链接和数组。请参阅 已弃用的方法。
可用的设置板块
Strapi 提供了插件可以扩展的内置设置板块:
global:通用应用设置permissions:管理面板设置
创建新的设置板块通常在 register 生命周期函数中完成,而向现有设置板块添加链接则在 bootstrap 中完成(因为目标板块可能由另一个插件注册)。两种形式都调用同一个 addSettingsLink() 方法,该方法在 register 的 app 参数上暴露,也作为 bootstrap 参数包中的 addSettingsLink 暴露。
to 的路径约定
to 参数根据上下文的不同表现不同:
| Context | to value | Final URL |
|---|---|---|
addMenuLink | /plugins/my-plugin | http://localhost:1337/admin/plugins/my-plugin |
addSettingsLink(带 section 对象) | my-plugin/general | http://localhost:1337/admin/settings/my-plugin/general |
addSettingsLink(带 section id) | my-plugin/documentation | http://localhost:1337/admin/settings/my-plugin/documentation |
对于菜单链接,路径相对于管理面板根目录(/admin)。对于设置链接,路径相对于设置路由(/admin/settings)。不要在设置链接路径中包含 settings/ 前缀。
链接上的 permissions 参数仅控制其在导航中的可见性。要完全保护你的插件页面并注册 RBAC 操作,请参阅 插件的管理面板权限 指南。
已弃用的方法
StrapiApp 实例上的以下方法已弃用。它们出于向后兼容仍可使用(两者内部都委托给 addSettingsLink()),但新代码应直接使用 addSettingsLink()。
createSettingSection(section, links)
此前用于在一次调用中注册新的设置板块及其初始链接。
// ❌ Deprecated
app.createSettingSection(
{ id: 'my-plugin', intlLabel: { id: 'my-plugin.settings.section-label', defaultMessage: 'My Plugin Settings' } },
[{ id: 'general', to: 'my-plugin/general', intlLabel: { id: 'my-plugin.settings.general', defaultMessage: 'General' }, Component: () => import('./pages/Settings/General') }],
);
// ✅ Replacement: pass the section object as the first argument to addSettingsLink
app.addSettingsLink(
{ id: 'my-plugin', intlLabel: { id: 'my-plugin.settings.section-label', defaultMessage: 'My Plugin Settings' } },
[{ id: 'general', to: 'my-plugin/general', intlLabel: { id: 'my-plugin.settings.general', defaultMessage: 'General' }, Component: () => import('./pages/Settings/General') }],
);
addSettingsLinks(sectionId, links)
此前用于在一次调用中向现有板块添加多个链接。单数形式的 addSettingsLink() 现在同时接受单个链接对象或数组。
// ❌ Deprecated
app.addSettingsLinks('global', [
{ id: 'general', to: 'my-plugin/general', intlLabel: { id: 'my-plugin.settings.general', defaultMessage: 'General' }, Component: () => import('./pages/Settings/General') },
{ id: 'advanced', to: 'my-plugin/advanced', intlLabel: { id: 'my-plugin.settings.advanced', defaultMessage: 'Advanced' }, Component: () => import('./pages/Settings/Advanced') },
]);
// ✅ Replacement: pass the array to addSettingsLink (singular)
app.addSettingsLink('global', [
{ id: 'general', to: 'my-plugin/general', intlLabel: { id: 'my-plugin.settings.general', defaultMessage: 'General' }, Component: () => import('./pages/Settings/General') },
{ id: 'advanced', to: 'my-plugin/advanced', intlLabel: { id: 'my-plugin.settings.advanced', defaultMessage: 'Advanced' }, Component: () => import('./pages/Settings/Advanced') },
]);
addSettingsLinks出于向后兼容仍暴露在bootstrap参数包中(与addSettingsLink、getPlugin和registerHook一同)。createSettingSection只能通过传入register(app)的完整app实例访问;它不是bootstrap参数包的一部分。- 两者内部都委托给
addSettingsLink(),并可能在未来的大版本中被移除。请在方便时进行迁移。