Skip to main content
AI/MLCrestApps

orchardcore-liquid

Skill for using Liquid templates in Orchard Core. Covers Liquid syntax, Orchard Core-specific filters and tags, shape rendering, content access, and Liquid best practices. Use this skill when requests mention Orchard Core Liquid, Write Liquid Templates, Global Objects, Content Item Access, Accessing Content Parts and Fields, Orchard Core Liquid Tags, or closely related Orchard Core implementation, setup, extension, or troubleshooting work. Strong matches include work with TitlePart, AutoroutePart, HtmlBodyPart, BodyPart, LiquidPart, MyPart, MyField, MyLiquidFilter, ILiquidFilter, LiquidTemplateContext, IServiceCollection, AddLiquidFilter. It also helps with liquid examples, Accessing Content Parts and Fields, Orchard Core Liquid Tags, Orchard Core Liquid Filters, plus the code patterns, admin flows, recipe steps, and referenced examples captured in this skill.

Stars
13
Source
CrestApps/CrestApps.AgentSkills
Updated
2026-05-29
Slug
CrestApps--CrestApps.AgentSkills--orchardcore-liquid
View on GitHubRaw SKILL.md

// install — copy + paste into any project

mkdir -p .claude/skills && curl -fsSL https://raw.githubusercontent.com/CrestApps/CrestApps.AgentSkills/HEAD/plugins/orchardcore/skills/orchardcore-liquid/SKILL.md -o .claude/skills/orchardcore-liquid.md

Drops the SKILL.md into .claude/skills/orchardcore-liquid.md. Works with Claude Code, Cursor, and any agent that loads SKILL.md files from .claude/skills/.

Orchard Core Liquid

Liquid templates use the .liquid extension and receive Orchard Core globals, shapes, filters, and tags.

{{ Site.SiteName }}
{{ Culture.Name }}
{{ User.Identity.Name }}
{{ Request.Path }}

Use Culture.Name for the current request culture; do not treat Site.Culture as the current UI culture.

Liquid Configuration and Slugs

The {% liquid %} tag is disabled by default in Orchard Core 3.0. Enable it only when the tenant requires nested Liquid source:

{
  "OrchardCore_Liquid": {
    "AllowLiquidTag": true
  }
}

The slugify filter transliterates Unicode text to an ASCII representation by default. Use the transliterate filter when transliteration is needed without slug normalization:

{{ "Crème brûlée" | slugify }}
{{ "Київ" | transliterate }}

The transliterate filter is provided by OrchardCore.Localization; enable that feature before using it in tenant templates.

Zones and Sections

zone is a block tag that adds its child content to a named layout zone. Use render_section to render a zone:

{% zone "Header" %}
  <span class="announcement">Welcome</span>
{% endzone %}

{% render_section "Header", required: false %}
{% render_section "Content", required: true %}

Shapes and Content Handles

{% shape "Menu", alias: "alias:main-menu" %}
{% contentitem alias: "alias:featured-article", display_type: "Summary" %}
{% contentitem id: "4j42fxryjcpqkkacmg6cwz3pr5" %}

An alias argument receives an Orchard content handle, including the alias: prefix. Render an already built shape with shape_render:

{{ Model.Content.HtmlBodyPart | shape_render }}

Content and Localized Text

{{ Model.ContentItem.DisplayText }}
{{ Model.ContentItem.Content.TitlePart.Title }}
{{ Model.ContentItem.Content.AutoroutePart.Path }}
{{ "Welcome to Orchard Core" | t }}
{{ "Hello {0}!" | t: User.Identity.Name }}

Use the t filter for localized UI text. Use normal Fluid control flow and Orchard filters for content:

{% if User | has_permission: "EditContent" %}
  <a href="{{ Model.ContentItem | edit_url }}">Edit</a>
{% endif %}

{% assign item = featuredContentItemId | content_item_id %}
{{ item.DisplayText }}

Custom Filters

using Fluid;
using Fluid.Values;

namespace MyModule;

public sealed class ReadingTimeFilter : ILiquidFilter
{
    public ValueTask<FluidValue> ProcessAsync(
        FluidValue input,
        FilterArguments arguments,
        LiquidTemplateContext context)
    {
        var wordCount = input.ToStringValue()
            .Split(' ', StringSplitOptions.RemoveEmptyEntries)
            .Length;

        return ValueTask.FromResult<FluidValue>(new StringValue($"{Math.Max(1, wordCount / 200)} min read"));
    }
}
services.AddLiquidFilter<ReadingTimeFilter>("reading_time");