Skip to main content

插件扩展

🌐 Plugins extension

Page summary:

现有插件可以通过将代码放置在 /src/extensions 或使用全局 register/bootstrap 钩子来覆盖。本手册中的说明涵盖了重塑插件内容类型模式或服务器逻辑 —— 尽管上游更新可能会破坏扩展。

Strapi 带有可以从 Marketplace 安装的插件,也可以作为 npm 包安装。你也可以创建自己的插件(参见 插件开发)或扩展现有插件。

🌐 Strapi comes with plugins that can be installed from the Marketplace or as npm packages. You can also create your own plugins (see plugins development) or extend the existing ones.

Warning
  • 任何插件更新都可能会破坏该插件的扩展。
  • 当需要时,Strapi 的新版本将会发布迁移指南,但这些指南从不涵盖插件扩展。如果需要进行大量自定义,请考虑分叉插件。
  • 目前,插件的管理面板部分只能使用 patch-package进行扩展,但请注意,这样做可能会在未来的 Strapi 版本中破坏你的插件。

插件扩展代码位于 ./src/extensions 文件夹(参见 项目结构)。一些插件会自动在该处创建文件,准备进行修改。

🌐 Plugin extensions code is located in the ./src/extensions folder (see project structure). Some plugins automatically create files there, ready to be modified.

扩展文件夹结构示例
/extensions
/some-plugin-to-extend
strapi-server.js|ts
/content-types
/some-content-type-to-extend
schema.json
/another-content-type-to-extend
schema.json
/another-plugin-to-extend
strapi-server.js|ts

插件可以通过两种方式扩展:

🌐 Plugins can be extended in 2 ways:

扩展插件的内容类型

🌐 Extending a plugin's content-types

插件的内容类型可以通过两种方式扩展:使用 strapi-server.js|ts 中的编程接口,以及通过重写内容类型的架构。

🌐 A plugin's Content-Types can be extended in 2 ways: using the programmatic interface within strapi-server.js|ts and by overriding the content-types schemas.

内容类型的最终架构取决于以下加载顺序:

🌐 The final schema of the content-types depends on the following loading order:

  1. 原始插件的内容类型,
  2. ./src/extensions/plugin-name/content-types/content-type-name/schema.json 中定义的 schema 中声明所覆盖的内容类型
  3. strapi-server.js|ts 导出的 contentTypes 中的内容类型声明
  4. Strapi 应用中 register() 函数 的内容类型声明

要覆盖插件的 content-types

🌐 To overwrite a plugin's content-types:

  1. (可选) 如果 ./src/extensions 文件夹尚不存在,请在应用根目录下创建该文件夹。
  2. 创建一个与要扩展的插件同名的子文件夹。
  3. 创建一个 content-types 子文件夹。
  4. content-types 子文件夹内,创建另一个与要覆盖的内容类型相同 singularName 的子文件夹。
  5. 在这个 content-types/name-of-content-type 子文件夹中,在一个 schema.json 文件中定义该内容类型的新架构(参见 schema 文档)。
  6. (可选) 对每种内容类型重复步骤 4 和 5 以进行覆盖。

扩展插件的界面

🌐 Extending a plugin's interface

当 Strapi 应用初始化时,插件、扩展和全局生命周期函数事件按以下顺序发生:

🌐 When a Strapi application is initializing, plugins, extensions and global lifecycle functions events happen in the following order:

  1. 插件已加载并公开其接口。
  2. ./src/extensions 中的文件已加载。
  3. ./src/index.js|ts 中的 register()bootstrap() 函数被调用。

插件的接口可以在步骤 2(即在 ./src/extensions 内)或步骤 3(即在 ./src/index.js|ts 内)进行扩展。

🌐 A plugin's interface can be extended at step 2 (i.e. within ./src/extensions) or step 3 (i.e. inside ./src/index.js|ts).

Note

如果你的 Strapi 项目是基于 TypeScript 的,请确保 index 文件具有 TypeScript 扩展名(即 src/index.ts),否则它将无法被编译。

🌐 If your Strapi project is TypeScript-based, please ensure that the index file has a TypeScript extension (i.e., src/index.ts) otherwise it will not be compiled.

在扩展文件夹内

🌐 Within the extensions folder

要使用 ./src/extensions 文件夹扩展插件的服务器接口:

🌐 To extend a plugin's server interface using the ./src/extensions folder:

  1. (可选) 如果 ./src/extensions 文件夹尚不存在,请在应用根目录下创建该文件夹。
  2. 创建一个与要扩展的插件同名的子文件夹。
  3. 创建一个 strapi-server.js|ts 文件,以使用 Server API 扩展插件的后端。
  4. 在此文件中,定义并导出一个函数。该函数接收 plugin 接口作为参数,以便可以扩展它。
后端扩展示例
./src/extensions/some-plugin-to-extend/strapi-server.js|ts

module.exports = (plugin) => {
plugin.controllers.controllerA.find = (ctx) => {};

plugin.policies[newPolicy] = (ctx) => {};

plugin.routes['content-api'].routes.push({
method: 'GET',
path: '/route-path',
handler: 'controller.action',
});

return plugin;
};
Note

strapi-server.js|ts 文件也是你可以通过替换上传插件的 generateFileName() 函数来覆盖图片功能的地方,从而生成自定义图片名称。

🌐 The strapi-server.js|ts file is also where you can override the image function, by replacing the Upload plugin's generateFileName() function so that it generates custom image names.

自定义文件命名逻辑示例
./src/extensions/upload/strapi-server.js|ts

module.exports = (plugin) => {
plugin.services['image-manipulation'].generateFileName = (file) => {
// Example: prefix a timestamp before the generated base name
return `${Date.now()}_${name}`;
};

return plugin;
};

generateFileName() 属于上传插件的 image-manipulation 服务,并期望一个单一的 name: string 参数。

Caution

此自定义依赖于内部上传插件服务(image-manipulation)。内部扩展点不是 Strapi 稳定的公共 API 的一部分,可能会在不同版本之间发生变化。

🌐 This customization relies on an internal Upload plugin service (image-manipulation). Internal extension points are not part of Strapi's stable public API and can change between versions.

在注册和引导函数中

🌐 Within the register and bootstrap functions

要在 ./src/index.js|ts 中扩展插件的接口,请使用整个项目的 bootstrap()register() 函数,并通过 getter 以编程方式访问接口。

🌐 To extend a plugin's interface within ./src/index.js|ts, use the bootstrap() and register() functions of the whole project, and access the interface programmatically with getters.

在 ./src/index.js|ts 中扩展插件内容类型的示例
./src/index.js|ts

module.exports = {
register({ strapi }) {
const contentTypeName = strapi.contentType('plugin::my-plugin.content-type-name')
contentTypeName.attributes = {
// Spread previous defined attributes
...contentTypeName.attributes,
// Add new, or override attributes
'toto': {
type: 'string',
}
}
},
bootstrap({ strapi }) {},
};