Skip to main content

服务器 API:内容类型

🌐 Server API: Content-types

Page summary:

服务器 API 从服务器入口文件导出一个 contentTypes 对象以声明插件内容类型。推荐的命名约定是对导出键和值 info.singularName 使用相同的值,以便在查询或清理数据时运行时 UID 保持可预测。

插件可以通过从 服务器入口文件 导出一个 contentTypes 对象来声明自己的内容类型。Strapi 在启动时会在插件命名空间下注册这些内容类型,并通过文档服务 API 和内容类型注册表提供访问。

🌐 A plugin can declare its own content-types by exporting a contentTypes object from the server entry file. Strapi registers these content-types under the plugin namespace at startup and makes them available through the Document Service API and the content-type registry.

Prerequisites

在深入了解本页的概念之前,请确保你已经:

🌐 Before diving deeper into the concepts on this page, please ensure you have:

声明

🌐 Declaration

contentTypes 导出是一个对象,其中每个键在插件命名空间下注册一种内容类型。为了避免混淆,该键应与模式中的 info.singularName 字段匹配。该值是一个对象,具有一个指向模式定义的 schema 属性。

🌐 The contentTypes export is an object where each key registers a content-type under the plugin namespace. To avoid confusion, the key should match the info.singularName field in the schema. The value is an object with a schema property pointing to the schema definition.

/src/plugins/my-plugin/server/src/content-types/index.js
'use strict';

const article = require('./article');

module.exports = {
article: { schema: article }, // recommended: keep key aligned with info.singularName
};
/src/plugins/my-plugin/server/src/content-types/article/schema.json
{
"kind": "collectionType",
"collectionName": "my_plugin_articles",
"info": {
"singularName": "article",
"pluralName": "articles",
"displayName": "Article"
},
"options": {
"draftAndPublish": false
},
"attributes": {
"title": {
"type": "string",
"required": true
},
"body": {
"type": "richtext"
}
}
}

UID 和命名规范

🌐 UIDs and naming conventions

当注册插件内容类型时,Strapi 会从插件命名空间和在 contentTypes 导出中使用的键构建其运行时 UID:

🌐 When a plugin content-type is registered, Strapi builds its runtime UID from the plugin namespace and the key used in the contentTypes export:

plugin::<plugin-name>.<content-types-key>

推荐的做法是设置 content-types-key === info.singularName。遵循这个做法可以使模式命名和运行时 UID 保持一致,并且更易于阅读。

🌐 The recommended convention is to set content-types-key === info.singularName. Following this convention keeps the schema naming and runtime UID aligned and easier to read.

当密钥匹配 singularName(推荐)时,生成的 UID 采用以下格式:

🌐 When the key matches singularName (recommended), the resulting UID follows this format:

plugin::<plugin-name>.<singular-name>

例如,一个名为 my-plugin 的插件,其内容类型的 singularNamearticle,导出键是 article,其 UID 是 plugin::my-plugin.article

🌐 For example, a plugin named my-plugin with a content-type whose singularName is article and export key article has the UID plugin::my-plugin.article.

Warning

如果 contentTypes 键和 info.singularName 出现分歧,getter 和查询将使用从注册键构建的 UID(而不是从 singularName 构建)。这可能会在你的插件代码中引入命名不一致。

🌐 If the contentTypes key and info.singularName diverge, getters and queries use the UID built from the registered key (not from singularName). This can introduce naming inconsistencies across your plugin code.

此 UID 在所有 API 中都保持一致使用:

🌐 This UID is used consistently across all APIs: | 用例 | 示例 || --- | --- || 通过文档服务查询 | strapi.documents('plugin::my-plugin.article').findMany() || 通过 getter 访问模式 | strapi.contentType('plugin::my-plugin.article') || 在路由处理程序中引用 | handler: 'article.find'(简短形式,通过插件注册表解析) || 传递给清理 API | strapi.contentAPI.sanitize.output(data, schema, { auth }) |

Note

控制器、服务、策略和中间件对全局 getter 使用相同的 plugin::<plugin-name>.<resource-name> UID 格式,但在插件级 API 中(例如路由 handlerpolicies)通过它们的短注册表键(例如 'article')进行引用。详情请参见 Getters & usage

运行时访问

🌐 Access at runtime

使用文档服务 API 进行查询

🌐 Querying with the Document Service API

使用文档服务 API 从控制器、服务或生命周期钩子中查询插件内容类型:

🌐 Use the Document Service API to query plugin content-types from controllers, services, or lifecycle hooks:

module.exports = ({ strapi }) => ({
async findAll(params = {}) {
return strapi.documents('plugin::my-plugin.article').findMany(params);
},

async create(data) {
return strapi.documents('plugin::my-plugin.article').create({ data });
},
});
Document Service API

有关可用方法和参数的完整列表,请参见 文档服务 API

🌐 For the full list of available methods and parameters, see the Document Service API.

访问架构

🌐 Accessing the schema

使用内容类型获取器来获取模式对象,例如将其传递给清理 API:

🌐 Use the content-type getter to retrieve the schema object, for example to pass it to the sanitization API:

const schema = strapi.contentType('plugin::my-plugin.article');

const sanitizedOutput = await strapi.contentAPI.sanitize.output(
data,
schema,
{ auth: ctx.state.auth }
);

最佳实践

🌐 Best practices

  • 将导出键精确匹配为 info.singularName 这样可以保持命名的可读性和一致性。在运行时,Strapi 会从插件命名空间下 contentTypes 映射的键中派生插件内容类型 UID。即使注册仍然成功,不匹配也可能会产生混乱的 UID 和维护问题。
  • 使用 collectionName 避免表名冲突。 collectionName 字段用于设置数据库表的名称。将其前缀加上插件名称(例如 my_plugin_articles),以避免与应用内容类型或其他插件发生冲突。
  • 将内容类型的模式保存在自己的文件中。 在名为 singularName 的子文件夹中,为每个模式定义一个专用的 schema.json 文件(例如,content-types/article/schema.json)。这与插件 SDK 生成的结构相匹配,并保持索引文件的可读性。
  • 仅在需要时启用 draftAndPublish 草稿和发布为内容类型添加了一个发布工作流程。仅在插件的使用场景需要时启用它,因为它会增加查询和内容管理的复杂性。