☰
Orchard Core Content Parts 完整指南:为内容类型装配可复用功能模块
2026/9/28 2:26:04 网站建设 项目流程
  • CMS
  • 后端
  • Web框架

【免费下载链接】OrchardCore

Orchard Core is an open-source modular and multi-tenant application framework built with ASP.NET Core, and a content management system (CMS) built on top of that framework.

项目地址:https://gitcode.com/gh_mirrors/or/OrchardCore
点击查看免费下载

Content Parts(内容部件)是 Orchard Core 内容类型系统的核心组合单元——每个 Part 为内容项(ContentItem)贡献一组可复用的字段、行为与编辑界面,从标题、别名、固定链接到表单、SEO 元数据均可通过"给内容类型添加部件"的方式即插即用。本篇以官方 Content Parts 参考文档为主线,结合仓库源码逐项拆解 18 种内置部件的用途、配置方式与底层实现,读完你将掌握在管理后台或 Recipe 中为内容类型装配部件、用 Liquid 模式生成标题与路由、以及通过 Placement 定制前端展示的完整实战能力。

什么是 Content Part

在 Orchard Core 中,内容类型(Content Type)由若干 Part 组合而成,Part 是对内容行为的模块化封装。从源码结构看,所有部件都继承自ContentPart基类(如 TitlePart 中public class TitlePart : ContentPart),并通过三块核心代码协作完成工作:

  • Model:定义部件承载的数据,例如 TitlePartSettings 保存标题生成模式等设置;
  • DisplayDriver:负责在内容编辑器(Edit形状)与前端(Detail/Summary形状)之间读写数据,见 TitlePartDisplayDriver.cs;
  • Handler:在内容项的创建、更新、发布等生命周期事件中执行逻辑,见 TitlePartHandler.cs。

如何给内容类型添加 Part

在管理后台(Admin UI)中,进入Content → Content Definition → Content Types,编辑目标内容类型,点击Add Parts即可从部件列表中挑选并附加;也可以为已附加的部件编辑设置。若需通过 Recipe 编程方式定义,可使用ContentDefinition步骤(完整示例见下文"用 Recipe 定义部件"一节)。

可用部件速查表

以下表格完整收录官方参考文档 Content Parts 中列出的内置部件:

名称描述详细文档
TitlePart允许你添加一个标题Title
AutoroutePart允许你添加固定链接(permalink)Autoroute
CommonPart允许编辑内容的创建日期与所有者Contents
AliasPart允许你添加一个别名Alias
HtmlBodyPart允许你添加 HTML 正文Html
MarkdownPart允许你添加 Markdown 正文Markdown
LiquidPart允许你添加 Liquid 输入Liquid
LocalizationPart允许你创建当前内容的本地化版本Localize
ListPart允许你添加一个列表Lists
FlowPart允许你添加 Widget(部件)Flow
BagPart允许你添加内嵌的内容项BagPart
WidgetsListPart允许你在不同区域(zones)中添加 Widget—
FormPart允许你添加一个表单Forms
Preview允许你添加一个预览按钮ContentPreview
PublishLater允许你设置日期以稍后发布PublishLater
ReCaptcha允许你添加一个 ReCaptchaReCaptcha
SeoMeta允许你配置 SEO 元标签Seo
AuditTrail允许你添加描述内容项变更的备注,并记录到审计日志AuditTrail

上述部件分布在多个功能模块中,启用对应模块的 Feature(位于Configuration → Features)后即可在内容类型编辑器中看到它们。

按职责分组理解部件

内容标识类:标题、别名与固定链接

TitlePart(OrchardCore.Title模块)让你自定义内容项的DisplayText属性——该属性贯穿整个管理后台,用于帮助识别内容项。除手动编辑外,还可以用 Liquid 表达式生成标题模式(Pattern),模式在内容项更新时执行,且能访问当前ContentItem。例如为带名为Name的 Text 字段的Product内容类型生成标题:

{{ ContentItem.Content.Product.Name.Text }}

AliasPart(OrchardCore.Alias模块)给内容项一个稳定的逻辑标识符,如main-menu、footer-widget。别名不是 URL——需要路由时请使用AutoroutePart。别名便于代码、模板、Recipe 与部署计划在不依赖环境特定内容项 ID 的情况下查找内容。其默认生成模式为:

{{ Model.ContentItem.DisplayText | slugify }}

注意:模式仅在别名当前为空时才被求值;修改显示文本或模式不会替换已有别名。别名需在租户内全局唯一,超过 735 个字符会被截断,且查找不区分大小写(索引统一小写存储)。通过alias:main-menu这样的句柄(handle),可在 Liquid(Content["alias:main-menu"])、Razor(Orchard.GetContentItemByAliasAsync("main-menu"))以及 C#(注入IContentHandleManager后调用GetContentItemIdAsync("alias:main-menu"))中解析内容。

AutoroutePart(OrchardCore.Autoroute模块)为内容项指定自定义 URL。在其设置中配置 Liquid 模式即可生成 slug,例如结合 TitlePart:

{{ ContentItem | display_text | slugify }}

若内容项位于容器内(例如BlogPost嵌套在带ListPart的Blog中),可结合容器与标题生成路径:

{{ ContentItem | container | display_text | slugify }}/{{ ContentItem | display_text | slugify }}

勾选Allow custom path可在编辑内容项时手动输入路径,勾选Show homepage options可将内容项设为首页。启用 Autoroute 后,可通过slug:<URL>句柄(如slug:my-blog/my-blog-post)在任意支持句柄的位置检索内容,Liquid 中写作:

{% assign my_content = Content["slug:my-blog/my-blog-post"] %}

或使用便捷访问器:

{% assign my_content = Content.Slug["my-blog/my-blog-post"] %}

AutoroutePart还支持容器路由:为父内容类型添加AutoroutePart、启用Allow contained item routing设置并在容器内容项上开启Route Contained Items,即可为BagPart内嵌项与Taxonomy的Term生成路由;默认路径由容器段 + 内容项 ID + DisplayText 组成,为子内容类型也附加AutoroutePart后可用 Liquid 模式生成友好 slug。相关设置还包括Allow Absolute Path(允许绝对路径)、Allow Disabled(允许编辑者关闭路由生成)以及Manage Contained Item Routes(对子内容类型单独管理路由)。

内容主体类:HTML、Markdown 与 Liquid

HtmlBodyPart(Html 模块)提供富 HTML 正文编辑器,适合文章、页面等富文本内容;MarkdownPart(Markdown 模块)提供 Markdown 编辑体验,前台渲染时转换为 HTML;LiquidPart(Liquid 模块)则允许编辑者输入 Liquid 模板片段,常用于需要动态输出的区域。三者均可在部件设置中配置编辑器外观(如 WYSIWYG 或源码模式)与默认提示文本。

结构组织类:列表、流式布局与内嵌内容

ListPart(Lists 模块)将内容项组织为有序列表,常用于"博客 → 博文"这类一对多的父子结构;FlowPart(Flows 模块)允许在内容项内部自由添加多种类型的 Widget;BagPart与 FlowPart 设计相似,但可以在设置中精确指定允许内嵌的内容类型,且可作为NamedPart附加(一个容器可有多个命名 BagPart,例如 TheAgencyTheme 主题中的 Services、Portfolio、About、Team 四个 BagPart)。BagPart 的全部内嵌内容项作为单一 JSON 文档存入数据库,这是其强大之处。BagPart 支持Blocks 编辑器(在部件设置中将 Editor 选项设为Blocks),使用基于模态框的内容类型选择器替代默认下拉菜单,并支持自定义Add Button Text与Modal Title Text。WidgetsListPart则允许在不同 Zone 中放置 Widget,常用于主题布局中的边栏、页脚等区域。

交互与扩展类:表单、预览与元数据

  • FormPart(Forms 模块):将内容项构建为可提交表单,配合字段部件可做自定义表单方案;
  • Preview(ContentPreview 模块):为内容编辑器增加"预览"按钮,编辑时即可查看渲染效果;
  • PublishLater(PublishLater 模块):设置未来发布日期,到期自动发布;
  • ReCaptcha(ReCaptcha 模块):为表单类内容添加人机验证;
  • SeoMeta(Seo 模块):配置标题、描述、社交分享标签等 SEO 元数据;
  • AuditTrail(AuditTrail 模块):记录内容项的变更说明与审计历史。

实战一:用 Liquid Pattern 配置 TitlePart

在内容类型定义中编辑TitlePart的设置,将Pattern填入 Liquid 表达式即可让标题自动生成。模式在内容项更新时执行,可使用字段参与生成。对应源码中,TitlePartHandler.cs 在UpdatedAsync事件中检查DisplayText是否为空,若为空则将TitlePart.Title写入ContentItem.DisplayText(part.ContentItem.DisplayText = part.Title);TitlePartDisplayDriver.cs 则在编辑与展示形状中读写model.Title = titlePart.ContentItem.DisplayText,并在保存时回写model.ContentItem.DisplayText = model.Title。这解释了标题为何在管理后台列表与前端展示中保持一致的DisplayText。

实战二:用 Placement 控制部件的前端展示与后台编辑器

Orchard Core 允许通过placement.json精确控制部件形状的位置。以TitlePart为例,其前端展示形状为TitlePart(Display Type 分别为Detail→ 默认位置Header:5、Summary→ 默认位置Header:10,模型类型均为TitlePartViewModel)。要隐藏前端标题:

{ "TitlePart": [ { "differentiator": "TitlePart", "place": "-" } ] }

若要在管理后台隐藏或移动编辑器,应针对包装形状ContentPart_Edit而非TitlePart_Edit,包装形状的 differentiator 为{ContentType}-{PartName}。例如隐藏Article内容类型编辑器上的 TitlePart 行:

{ "ContentPart_Edit": [ { "differentiator": "Article-TitlePart", "place": "-" } ] }

TitlePart_Edit只作用于内部编辑器形状;需要隐藏或移动包含标签与说明的整行编辑器时,请使用ContentPart_Edit。BagPart的 Placement 规则与此一致:命名 BagPart 用部件名作为 differentiator(如Services),隐藏其编辑器则针对LandingPage-Services(非命名 BagPart 为LandingPage-BagPart),详见 BagPart.md。

实战三:用 Recipe 定义部件

除后台操作外,部件可完全通过 Recipe 的ContentDefinition步骤编程定义。以下示例将AliasPart附加到Article内容类型,并设置 Liquid 模式与"生成后禁用输入"选项(GeneratedDisabled),同时指定其在编辑器中的位置:

{ "steps": [ { "name": "ContentDefinition", "ContentTypes": [ { "Name": "Article", "DisplayName": "Article", "Settings": { "ContentTypeSettings": { "Creatable": true, "Draftable": true, "Versionable": true } }, "ContentTypePartDefinitionRecords": [ { "PartName": "AliasPart", "Name": "AliasPart", "Settings": { "AliasPartSettings": { "Pattern": "{{ Model.ContentItem | display_text | slugify }}", "Options": "GeneratedDisabled" }, "ContentTypePartSettings": { "Position": "0" } } } ] } ] } ] }

若允许编辑者覆盖生成值,将Options改为"Editable"。对应的AliasPartSettings选项还包括:Alias is editable(编辑者可输入别名,留空且配置了模式时由系统生成)与Alias is generated and input is disabled(编辑器显示为禁用输入框,别名为空时按模式生成)。

部件渲染与形状机制

从前端角度看,附加部件的形状渲染遵循统一规则:Detail与Summary两种显示类型对应不同的模板与默认位置;TitlePart的TitlePartViewModel提供Title(字符串)与TitlePart(部件实例)两个属性供模板使用。BagPart 等复合部件还支持标准 alternates 与命名 alternates——例如MyBag-BagPart.liquid(内容类型 + BagPart)与MyBag-MyNamedBagPart.liquid(内容类型 + 命名 BagPart)。显示内嵌内容项时,Liquid 使用shape_build_display与shape_render过滤器,Razor 则注入IContentItemDisplayManager调用BuildDisplayAsync后经DisplayAsync渲染(BagPart.md)。

延伸阅读

  • ContentParts 官方参考
  • Title 模块文档 与 TitlePart 源码
  • Autoroute 模块文档
  • Alias 模块文档
  • Flow / BagPart 文档 与 BagPart.md
  • Html、Markdown、Liquid、Lists、Forms、Seo、AuditTrail 等模块文档
  • CMS
  • 后端
  • Web框架

【免费下载链接】OrchardCore

Orchard Core is an open-source modular and multi-tenant application framework built with ASP.NET Core, and a content management system (CMS) built on top of that framework.

项目地址:https://gitcode.com/gh_mirrors/or/OrchardCore
点击查看免费下载
上一篇:BepInEx vs UMM:RuntimeUnityEditor不同加载器版本对比与选择指南
下一篇:FLAC元数据管理:如何用metaflac完美编辑音频标签

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询