扩展 Extension

Strapi 附带插件,可从市场或作为 npm 包安装。您还可以创建自己的插件请参阅插件开发或扩展现有插件。

Strapi 附带 插件,可从 市场 或作为 npm 包安装。您还可以创建自己的插件(请参阅 插件开发)或扩展现有插件。

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

插件扩展代码位于 ./src/extensions 文件夹中(请参阅 项目结构)。一些插件会自动在那里创建文件,以供修改。

扩展文件夹结构示例

bash
/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

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

扩展插件的内容类型

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

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

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

要覆盖插件的 内容类型

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

扩展插件的接口

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

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

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

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

在扩展文件夹中

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

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

后端扩展示例

./src/extensions/some-plugin-to-extend/strapi-server.js|ts
js
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
}

在 register 和 bootstrap 函数中

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

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

./src/index.js|ts
js
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 }) {},
}