Get the FREE Ultimate OpenClaw Setup Guide →

orchardcore-content-parts

Scanned
npx machina-cli add skill CrestApps/CrestApps.AgentSkills/orchardcore-content-parts --openclaw
Files (1)
SKILL.md
11.9 KB

Orchard Core Content Parts - Prompt Templates

Add and Configure Content Parts

You are an Orchard Core expert. Generate migration code and recipes for attaching and configuring built-in content parts.

Guidelines

  • Parts are attached to content types using AlterTypeDefinitionAsync in a migration.
  • Each part has specific settings that control its behavior.
  • Part settings are applied via .WithSettings(new XxxPartSettings { ... }).
  • Use .WithPosition("N") to control the order of parts in the editor.
  • Third-party modules providing parts (CrestApps, Lombiq, etc.) must be installed as NuGet packages in the web project (the startup project of the solution), not just in the module project.
  • Always seal classes.

General Pattern for Attaching a Part

await _contentDefinitionManager.AlterTypeDefinitionAsync("{{ContentType}}", type => type
    .WithPart("{{PartName}}", part => part
        .WithPosition("{{Position}}")
        .WithSettings(new {{PartName}}Settings
        {
            // Part-specific settings
        })
    )
);

TitlePart

Provides a title/display text for a content item. Feature: OrchardCore.Title.

TitlePart Settings

SettingTypeDefaultDescription
OptionsTitlePartOptionsEditableTitle behavior: Editable, GeneratedDisabled, GeneratedHidden, EditableRequired.
Patternstring""Liquid pattern to generate the title (used with GeneratedDisabled or GeneratedHidden).
RenderTitlebooltrueWhether to render the title in the content shape.

TitlePart Migration

await _contentDefinitionManager.AlterTypeDefinitionAsync("{{ContentType}}", type => type
    .WithPart("TitlePart", part => part
        .WithPosition("0")
        .WithSettings(new TitlePartSettings
        {
            Options = TitlePartOptions.EditableRequired,
            RenderTitle = true
        })
    )
);

TitlePart with Generated Title

await _contentDefinitionManager.AlterTypeDefinitionAsync("{{ContentType}}", type => type
    .WithPart("TitlePart", part => part
        .WithPosition("0")
        .WithSettings(new TitlePartSettings
        {
            Options = TitlePartOptions.GeneratedDisabled,
            Pattern = "{{ ContentItem.Content.{{ContentType}}.Name.Text }} - {{ ContentItem.Content.{{ContentType}}.Date.Value | date: '%Y-%m-%d' }}"
        })
    )
);

AutoroutePart

Generates a URL (slug) for a content item. Feature: OrchardCore.Autoroute.

AutoroutePart Settings

SettingTypeDefaultDescription
AllowCustomPathboolfalseWhether users can define a custom path.
Patternstring"{{ ContentItem.DisplayText | slugify }}"Liquid pattern to generate the slug.
ShowHomepageOptionboolfalseWhether to show the "Set as homepage" option.
AllowUpdatePathboolfalseWhether to allow re-generating the path on data change.
AllowDisabledboolfalseWhether to allow disabling autoroute on individual items.
AllowRouteContainedItemsboolfalseWhether to route contained items.
ManageContainedItemRoutesboolfalseWhether this part manages contained item routes.
AllowAbsolutePathboolfalseWhether to allow absolute paths for contained items.

AutoroutePart Migration

await _contentDefinitionManager.AlterTypeDefinitionAsync("{{ContentType}}", type => type
    .WithPart("AutoroutePart", part => part
        .WithPosition("1")
        .WithSettings(new AutoroutePartSettings
        {
            AllowCustomPath = true,
            ShowHomepageOption = false,
            Pattern = "{{ ContentItem.DisplayText | slugify }}",
            AllowUpdatePath = true
        })
    )
);

HtmlBodyPart

Provides a rich HTML body editor. Feature: OrchardCore.Html.

HtmlBodyPart Settings

SettingTypeDefaultDescription
SanitizeHtmlbooltrueWhether to sanitize HTML content.

HtmlBodyPart Editors

EditorDescription
(default)Standard rich text editor.
WysiwygWYSIWYG HTML editor.
TrumbowygTrumbowyg WYSIWYG editor.
MonacoMonaco code editor.

HtmlBodyPart Migration

await _contentDefinitionManager.AlterTypeDefinitionAsync("{{ContentType}}", type => type
    .WithPart("HtmlBodyPart", part => part
        .WithPosition("2")
        .WithEditor("Wysiwyg")
        .WithSettings(new HtmlBodyPartSettings
        {
            SanitizeHtml = true
        })
    )
);

MarkdownBodyPart

Provides a Markdown body editor. Feature: OrchardCore.Markdown.

MarkdownBodyPart Settings

SettingTypeDefaultDescription
SanitizeHtmlbooltrueWhether to sanitize HTML output.

MarkdownBodyPart Migration

await _contentDefinitionManager.AlterTypeDefinitionAsync("{{ContentType}}", type => type
    .WithPart("MarkdownBodyPart", part => part
        .WithPosition("2")
        .WithSettings(new MarkdownBodyPartSettings
        {
            SanitizeHtml = true
        })
    )
);

ListPart

Makes a content type a container for other content items. Feature: OrchardCore.Lists.

ListPart Settings

SettingTypeDefaultDescription
PageSizeint10Number of items to display per page.
EnableOrderingboolfalseWhether to allow manual ordering.
ContainedContentTypesstring[][]Content types that can be contained.
ShowHeaderbooltrueWhether to show the list header.

ListPart Migration

await _contentDefinitionManager.AlterTypeDefinitionAsync("Blog", type => type
    .WithPart("ListPart", part => part
        .WithPosition("3")
        .WithSettings(new ListPartSettings
        {
            PageSize = 10,
            EnableOrdering = false,
            ContainedContentTypes = new[] { "BlogPost" },
            ShowHeader = true
        })
    )
);

FlowPart

Enables a content type to contain a flow of widget content items. Feature: OrchardCore.Flows.

FlowPart Settings

SettingTypeDefaultDescription
ContainedContentTypesstring[][]Content types that can be added to the flow.

FlowPart Migration

await _contentDefinitionManager.AlterTypeDefinitionAsync("{{ContentType}}", type => type
    .WithPart("FlowPart", part => part
        .WithPosition("3")
        .WithSettings(new FlowPartSettings
        {
            ContainedContentTypes = new[] { "HtmlWidget", "ImageWidget", "BlockQuote" }
        })
    )
);

BagPart

A container part allowing nested content items within a content item. Feature: OrchardCore.Flows.

BagPart Settings

SettingTypeDefaultDescription
ContainedContentTypesstring[][]Content types that can be added to the bag.
DisplayTypestring"Detail"Display type for rendering bag items.

BagPart Migration

await _contentDefinitionManager.AlterTypeDefinitionAsync("{{ContentType}}", type => type
    .WithPart("BagPart", "{{BagPartName}}", part => part
        .WithDisplayName("{{DisplayName}}")
        .WithPosition("4")
        .WithSettings(new BagPartSettings
        {
            ContainedContentTypes = new[] { "Slide", "Testimonial" }
        })
    )
);

AliasPart

Provides an alias identifier for a content item. Feature: OrchardCore.Alias.

AliasPart Settings

SettingTypeDefaultDescription
Patternstring""Liquid pattern to generate the alias.

AliasPart Migration

await _contentDefinitionManager.AlterTypeDefinitionAsync("{{ContentType}}", type => type
    .WithPart("AliasPart", part => part
        .WithPosition("1")
        .WithSettings(new AliasPartSettings
        {
            Pattern = "{{ ContentItem.DisplayText | slugify }}"
        })
    )
);

PublishLaterPart

Allows scheduling future publish dates. Feature: OrchardCore.PublishLater.

PublishLaterPart Migration

await _contentDefinitionManager.AlterTypeDefinitionAsync("{{ContentType}}", type => type
    .WithPart("PublishLaterPart", part => part
        .WithPosition("5")
    )
);

LocalizationPart

Enables content localization (translation). Feature: OrchardCore.ContentLocalization.

LocalizationPart Migration

await _contentDefinitionManager.AlterTypeDefinitionAsync("{{ContentType}}", type => type
    .WithPart("LocalizationPart", part => part
        .WithPosition("6")
    )
);

TaxonomyPart

Makes a content type act as a taxonomy container. Feature: OrchardCore.Taxonomies.

TaxonomyPart Settings

SettingTypeDefaultDescription
TermContentTypestring""The content type to use for terms.

TaxonomyPart Migration

await _contentDefinitionManager.AlterTypeDefinitionAsync("{{TaxonomyType}}", type => type
    .WithPart("TitlePart", part => part.WithPosition("0"))
    .WithPart("TaxonomyPart", part => part
        .WithPosition("1")
        .WithSettings(new TaxonomyPartSettings
        {
            TermContentType = "{{TermContentType}}"
        })
    )
);

SeoMetaPart

Provides SEO metadata (meta title, description, etc.). Feature: OrchardCore.Seo.

SeoMetaPart Migration

await _contentDefinitionManager.AlterTypeDefinitionAsync("{{ContentType}}", type => type
    .WithPart("SeoMetaPart", part => part
        .WithPosition("10")
    )
);

PreviewPart

Enables content preview. Feature: OrchardCore.ContentPreview.

PreviewPart Settings

SettingTypeDefaultDescription
Patternstring""Liquid pattern for the preview URL.

PreviewPart Migration

await _contentDefinitionManager.AlterTypeDefinitionAsync("{{ContentType}}", type => type
    .WithPart("PreviewPart", part => part
        .WithPosition("11")
        .WithSettings(new PreviewPartSettings
        {
            Pattern = "{{ ContentItem | display_url }}"
        })
    )
);

Content Type Options

When defining a content type, these options control the content type behavior:

await _contentDefinitionManager.AlterTypeDefinitionAsync("{{ContentType}}", type => type
    .DisplayedAs("{{DisplayName}}")
    .Creatable()        // Can be created from the admin
    .Listable()         // Appears in content listings
    .Draftable()        // Supports draft versions
    .Versionable()      // Supports versioning
    .Securable()        // Supports per-content permissions
    .Stereotype("{{Stereotype}}") // Set a stereotype (e.g., "Widget", "MenuItem")
);

Installing Third-Party Part Modules

Modules that provide custom parts from external sources (CrestApps, Lombiq, or community modules) must be installed as NuGet packages in the web project (the startup project of the solution):

<Project Sdk="Microsoft.NET.Sdk.Web">
  <ItemGroup>
    <!-- Orchard Core base -->
    <PackageReference Include="OrchardCore.Application.Cms.Targets" Version="2.*" />

    <!-- Third-party modules must be added to the web project -->
    <PackageReference Include="CrestApps.OrchardCore.AI" Version="1.*" />
    <PackageReference Include="Lombiq.HelpfulExtensions.OrchardCore" Version="1.*" />
  </ItemGroup>
</Project>

For local project references to third-party modules:

<ItemGroup>
  <!-- Local third-party module project reference in the web project -->
  <ProjectReference Include="../ThirdParty.Module/ThirdParty.Module.csproj" />
</ItemGroup>

Source

git clone https://github.com/CrestApps/CrestApps.AgentSkills/blob/main/src/CrestApps.AgentSkills/orchardcore/orchardcore-content-parts/SKILL.mdView on GitHub

Overview

This skill helps you add and configure built-in Orchard Core content parts on content types. It covers every built-in part, exposes their settings, and provides migration patterns and recipe configurations to reproduce setups reliably.

How This Skill Works

Parts are attached to content types via migrations using AlterTypeDefinitionAsync. Each part is configured with a position and part-specific settings using WithSettings and the appropriate PartSettings type. The guidance emphasizes sealing classes and ensuring third party parts are installed as NuGet packages in the startup project, not just the module project.

When to Use It

  • When you need to attach a built-in part to a content type in a migration
  • When you want to configure a part’s settings (for example TitlePart Options, RenderTitle, or Pattern) during setup
  • When generating migrations and recipes to reproduce content type schemas across environments
  • When controlling the editor order of parts with WithPosition
  • When integrating third-party part modules and ensuring they are installed as NuGet packages in the startup project

Quick Start

  1. Step 1: Identify the target content type and the built-in parts to attach (e.g., TitlePart, AutoroutePart).
  2. Step 2: Create a migration using AlterTypeDefinitionAsync and attach the part with WithPosition and WithSettings using the correct PartSettings type.
  3. Step 3: Run the migration, verify the editor layout, and test any patterns or settings in the content editor

Best Practices

  • Seal all classes as required by the guidelines
  • Attach parts using the correct ContentType and PartName, and assign a precise position with WithPosition
  • Use the proper PartSettings type for each part and populate relevant fields
  • Install third-party modules as NuGet packages in the startup project, not only in the module project
  • Test migrations and recipes in a staging environment to verify behavior and editor layout

Example Use Cases

  • Attach TitlePart to a content type with position 0 and set Options to EditableRequired with RenderTitle enabled (TitlePartMigration example).
  • Attach TitlePart with Generated title, using GeneratedDisabled and a Pattern to compute the title from content fields (TitlePart with Generated Title example).
  • Configure AutoroutePart with a custom path option and a slug pattern to generate the URL slug (AutoroutePart Settings example).
  • Use the general migration pattern to attach a part to a content type with a specific position and settings (General Part Attachment example).
  • Adjust editor order by setting different WithPosition values to control how parts appear in the content editor (Positioning example).

Frequently Asked Questions

Add this skill to your agents
Sponsor this space

Reach thousands of developers