插件扩展
¥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 the plugin's interface (e.g. to add controllers, services, policies, middlewares and more)
扩展插件的内容类型
¥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:
原始插件的内容类型,
¥the content-types of the original plugin,
被
./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
从
strapi-server.js|ts
导出的content-types
密钥 中的内容类型声明¥the content-types declarations in the
content-types
key exported fromstrapi-server.js|ts
Strapi 应用
register()
功能 中的内容类型声明¥the content-types declarations in the
register()
function of the Strapi application
要覆盖插件的 content-types:
¥To overwrite a plugin's content-types:
(可选)如果该文件夹尚不存在,请在应用的根目录中创建
./src/extensions
文件夹。¥(optional) Create the
./src/extensions
folder at the root of the app, if the folder does not already exist.创建一个与要扩展的插件同名的子文件夹。
¥Create a subfolder with the same name as the plugin to be extended.
创建
content-types
子文件夹。¥Create a
content-types
subfolder.在
content-types
子文件夹内,创建另一个与 singularName 相同的子文件夹作为要覆盖的内容类型。¥Inside the
content-types
subfolder, create another subfolder with the same singularName as the content-type to overwrite.在此
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 aschema.json
file (see schema documentation).(可选)对每个要覆盖的内容类型重复步骤 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:
插件已加载并公开其接口。
¥Plugins are loaded and their interfaces are exposed.
加载
./src/extensions
中的文件。¥Files in
./src/extensions
are loaded.调用
./src/index.js|ts
中的register()
和bootstrap()
函数。¥The
register()
andbootstrap()
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:
(可选)如果该文件夹尚不存在,请在应用的根目录中创建
./src/extensions
文件夹。¥(optional) Create the
./src/extensions
folder at the root of the app, if the folder does not already exist.创建一个与要扩展的插件同名的子文件夹。
¥Create a subfolder with the same name as the plugin to be extended.
创建
strapi-server.js|ts
文件以使用 服务器 API 扩展插件的后端。¥Create a
strapi-server.js|ts
file to extend a plugin's back end using the Server API.在此文件中,定义并导出一个函数。该函数接收
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
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
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 }) {},
};