Skip to main content

插件扩展

¥Plugins extension

Strapi 附带 plugins,可以从 市场 或作为 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.

⚠️ 警告
  • 任何插件更新都可能会破坏该插件的扩展。

    ¥Any plugin update could break this plugin's extensions.

  • Strapi 的新版本将在需要时发布迁移指南,但这些指南从不涵盖插件扩展。如果需要大量自定义,请考虑分叉插件。

    ¥New versions of Strapi will be released with migration guides when required, but these guides never cover plugin extensions. Consider forking a plugin if extensive customizations are required.

  • 目前,插件的管理面板部分只能使用 patch-package 进行扩展,但请考虑这样做可能会在 Strapi 的未来版本中破坏你的插件。

    ¥Currently, the admin panel part of a plugin can only be extended using patch-package, but please consider that doing so might break your plugin in future versions of 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.

Example of extensions folder structure
/extensions
/some-plugin-to-extend
strapi-server.js|ts
/content-types
/some-content-type-to-extend
model.json
/another-content-type-to-extend
model.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. 原始插件的内容类型,

    ¥the content-types of the original plugin,

  2. ./src/extensions/plugin-name/content-types/content-type-name/schema.json 中定义的 schema 中的声明覆盖的内容类型

    ¥the content-types overridden by the declarations in the schema defined in ./src/extensions/plugin-name/content-types/content-type-name/schema.json

  3. strapi-server.js|ts 导出的 content-types 密钥 中的内容类型声明

    ¥the content-types declarations in the content-types key exported from strapi-server.js|ts

  4. Strapi 应用 register() 功能 中的内容类型声明

    ¥the content-types declarations in the register() function of the Strapi application

要覆盖插件的 content-types

¥To overwrite a plugin's content-types:

  1. (可选)如果该文件夹尚不存在,请在应用的根目录中创建 ./src/extensions 文件夹。

    ¥(optional) Create the ./src/extensions folder at the root of the app, if the folder does not already exist.

  2. 创建一个与要扩展的插件同名的子文件夹。

    ¥Create a subfolder with the same name as the plugin to be extended.

  3. 创建 content-types 子文件夹。

    ¥Create a content-types subfolder.

  4. content-types 子文件夹内,创建另一个与 singularName 相同的子文件夹作为要覆盖的内容类型。

    ¥Inside the content-types subfolder, create another subfolder with the same singularName as the content-type to overwrite.

  5. 在此 content-types/name-of-content-type 子文件夹内,为 schema.json 文件中的内容类型定义新架构(请参阅 schema 文档)。

    ¥Inside this content-types/name-of-content-type subfolder, define the new schema for the content-type in a schema.json file (see schema documentation).

  6. (可选)对每个要覆盖的内容类型重复步骤 4 和 5。

    ¥(optional) Repeat steps 4 and 5 for each content-type to overwrite.

扩展插件的接口

¥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. 插件已加载并公开其接口。

    ¥Plugins are loaded and their interfaces are exposed.

  2. 加载 ./src/extensions 中的文件。

    ¥Files in ./src/extensions are loaded.

  3. 调用 ./src/index.js|ts 中的 register()bootstrap() 函数。

    ¥The register() and bootstrap() functions in ./src/index.js|ts are called.

插件的接口可以在步骤 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).

✏️ 注意

如果你的 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 文件夹。

    ¥(optional) Create the ./src/extensions folder at the root of the app, if the folder does not already exist.

  2. 创建一个与要扩展的插件同名的子文件夹。

    ¥Create a subfolder with the same name as the plugin to be extended.

  3. 创建 strapi-server.js|ts 文件以使用 服务器 API 扩展插件的后端。

    ¥Create a strapi-server.js|ts file to extend a plugin's back end using the Server API.

  4. 在此文件中,定义并导出一个函数。该函数接收 plugin 接口作为参数,以便可以对其进行扩展。

    ¥Within this file, define and export a function. The function receives the plugin interface as an argument so it can be extended.

Example of backend extension
./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;
};

在注册和引导函数内

¥Within the register and bootstrap functions

要在 ./src/index.js|ts 内扩展插件的接口,请使用整个项目的 bootstrap()register() functions,并使用 getters 以编程方式访问该接口。

¥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.

Example of extending a plugin's content-type within ./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 }) {},
};