Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
crestapps avatar

Orchardcore Widgets

  • 1 installs
  • 13 repo stars
  • Updated August 3, 2026
  • crestapps/crestapps.agentskills

Build reusable Orchard Core widgets for page content and layout composition.

About

OrchardCore Widgets skill guides agents through widget development, registration, and rendering in Orchard Core applications.

  • Widget registration and lifecycle
  • Widget rendering patterns

Orchardcore Widgets by the numbers

  • 1 all-time installs (skills.sh)
  • Ranked #1,912 of 2,245 Frontend Development skills by installs in the Skillselion catalog
  • Data as of Aug 4, 2026 (Skillselion catalog sync)
npx skills add https://github.com/crestapps/crestapps.agentskills --skill orchardcore-widgets

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs1
repo stars13
Last updatedAugust 3, 2026
Repositorycrestapps/crestapps.agentskills

What it does

Build reusable Orchard Core widgets for page content and layout composition.

Files

SKILL.mdMarkdownGitHub ↗

Orchard Core Widgets - Prompt Templates

Create and Manage Widgets

You are an Orchard Core expert. Generate widget definitions, layer configurations, and zone placement for Orchard Core.

Guidelines

  • Widgets are content types with the Widget stereotype.
  • Widgets are placed in zones defined by the theme layout.
  • Layers control when widgets are visible using rule expressions.
  • Enable OrchardCore.Widgets and OrchardCore.Layers for widget support.
  • Each widget is a content item that can be edited from the admin panel.
  • Layer rules use JavaScript-like expressions to control visibility.
  • Use FlowPart to allow widgets inside content items.
  • WidgetsListPart editor wrapper placement uses ContentPart_Edit with differentiator {ContentType}-{PartName}.
  • WidgetsListPart does not render its own front-end display shape; it injects widgets directly into layout zones.

Enabling Widget Features

{
  "steps": [
    {
      "name": "Feature",
      "enable": [
        "OrchardCore.Widgets",
        "OrchardCore.Layers",
        "OrchardCore.Flows"
      ],
      "disable": []
    }
  ]
}

Creating a Widget Content Type

public sealed class Migrations : DataMigration
{
    private readonly IContentDefinitionManager _contentDefinitionManager;

    public Migrations(IContentDefinitionManager contentDefinitionManager)
    {
        _contentDefinitionManager = contentDefinitionManager;
    }

    public async Task<int> CreateAsync()
    {
        await _contentDefinitionManager.AlterTypeDefinitionAsync("{{WidgetName}}", type => type
            .DisplayedAs("{{WidgetDisplayName}}")
            .Stereotype("Widget")
            .WithPart("{{WidgetName}}", part => part
                .WithPosition("0")
            )
        );

        await _contentDefinitionManager.AlterPartDefinitionAsync("{{WidgetName}}", part => part
            .WithField("{{FieldName}}", field => field
                .OfType("{{FieldType}}")
                .WithDisplayName("{{FieldDisplayName}}")
                .WithPosition("0")
            )
        );

        return 1;
    }
}

Layer Configuration via Recipe

{
  "steps": [
    {
      "name": "Layers",
      "Layers": [
        {
          "Name": "Always",
          "LayerRule": {
            "Conditions": [
              {
                "Name": "BooleanCondition",
                "Value": true
              }
            ]
          },
          "Description": "Widgets on this layer are always displayed."
        },
        {
          "Name": "Homepage",
          "LayerRule": {
            "Conditions": [
              {
                "Name": "UrlCondition",
                "Value": "^/$"
              }
            ]
          },
          "Description": "Widgets on this layer are displayed on the homepage."
        },
        {
          "Name": "Authenticated",
          "LayerRule": {
            "Conditions": [
              {
                "Name": "IsAuthenticatedCondition",
                "Value": true
              }
            ]
          },
          "Description": "Widgets on this layer are displayed for authenticated users."
        }
      ]
    }
  ]
}

Layer Rule Expressions

Common layer rule conditions:

  • UrlCondition - Match by URL pattern (regex): ^/$ (homepage), ^/blog/.* (blog section).
  • IsAuthenticatedCondition - Visible for authenticated users.
  • IsAnonymousCondition - Visible for anonymous users.
  • RoleCondition - Visible for specific roles.
  • CultureCondition - Visible for specific cultures.
  • BooleanCondition - Always true/false.
  • JavascriptCondition - Custom JavaScript expression.

Placing Widgets in Zones

Widgets are assigned to zones and layers via the admin UI or recipes:

{
  "steps": [
    {
      "name": "Content",
      "data": [
        {
          "ContentItemId": "widget-hero-banner",
          "ContentType": "HeroBanner",
          "DisplayText": "Welcome Banner",
          "Latest": true,
          "Published": true,
          "LayerMetadata": {
            "Layer": "Homepage",
            "Zone": "Header",
            "Position": 0
          },
          "HeroBanner": {
            "Heading": {
              "Text": "Welcome to Our Site"
            },
            "Description": {
              "Html": "<p>Your one-stop solution.</p>"
            }
          }
        }
      ]
    }
  ]
}

Widget Template (Liquid)

Create a template at Views/Widget-{{WidgetName}}.liquid:

<div class="widget widget-{{ Model.ContentItem.ContentType | downcase }}">
    <h3>{{ Model.ContentItem.Content.{{WidgetName}}.Heading.Text }}</h3>
    <div class="widget-body">
        {{ Model.ContentItem.Content.{{WidgetName}}.Body.Html }}
    </div>
</div>

Widget Template (Razor)

Create a template at Views/Widget-{{WidgetName}}.cshtml:

@model OrchardCore.ContentManagement.ContentItem

<div class="widget">
    <h3>@Model.Content.{{WidgetName}}.Heading.Text</h3>
    <div class="widget-body">
        @Html.Raw(Model.Content.{{WidgetName}}.Body.Html)
    </div>
</div>

FlowPart for Inline Widgets

Allow widgets inside content items using FlowPart:

await _contentDefinitionManager.AlterTypeDefinitionAsync("Page", type => type
    .WithPart("FlowPart")
);

FlowPart allows editors to add widgets inline within content item editing.

WidgetsListPart Editor Placement

To hide or move the whole WidgetsListPart editor row in the admin UI:

{
  "ContentPart_Edit": [
    {
      "differentiator": "PlacementTest-WidgetsListPart",
      "place": "-"
    }
  ]
}

If the part is attached as a named part, replace WidgetsListPart with the part name.

Common Built-in Widget Types

  • HtmlWidget - Renders custom HTML content.
  • LiquidWidget - Renders Liquid template content.
  • MenuWidget - Renders a menu.
  • ContainerWidget - Contains other widgets in a layout.

Widget Best Practices

  • Use the Widget stereotype for all widget content types.
  • Keep widget templates small and focused.
  • Use layer rules to control visibility instead of conditional logic in templates.
  • Test widgets across different zones and screen sizes.
  • Use FlowPart for content-embedded widgets.

Related skills

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.