Orchard Core Razor Views - Prompt Templates
_ViewImports.cshtml Setup
Every Orchard Core theme or module should include a _ViewImports.cshtml file at the root of its Views folder.
Minimum Required Directives
@inherits OrchardCore.DisplayManagement.Razor.RazorPage<TModel>
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@addTagHelper *, OrchardCore.DisplayManagement
@addTagHelper *, OrchardCore.ResourceManagement
@addTagHelper *, OrchardCore.Menu
@addTagHelper *, OrchardCore.Contents
@addTagHelper *, OrchardCore.Media
@using OrchardCore.DisplayManagement
@using OrchardCore.DisplayManagement.Shapes
@using OrchardCore.ContentManagement
@using Microsoft.AspNetCore.Html
Guidelines
@inherits OrchardCore.DisplayManagement.Razor.RazorPage<TModel>gives access toIOrchardHelperviaOrchardand shape display helpers.- Add only the
@addTagHelperlines for assemblies your theme or module actually uses. @using OrchardCore.DisplayManagement.Razoris not needed when@inheritsalready references that namespace.- For themes, add
@using OrchardCoreto access general extension methods.
_ViewStart.cshtml Conventions
@{
Layout = "Layout";
}
- Place
_ViewStart.cshtmlin theViewsfolder to set the default layout. "Layout"references the shape namedLayoutwhich resolves toLayout.cshtml.- Modules typically do not set a layout in
_ViewStart.cshtmlbecause their views render inside the theme's layout automatically. - Override per-view by setting
Layout = null;for partial or layoutless pages.
Layout Rendering Patterns
A theme's Layout.cshtml renders zones that contain shapes placed by modules and the admin UI.
Minimal Layout Template
@{
var body = await RenderBodyAsync();
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@RenderTitleSegments(Site.SiteName)</title>
<resources type="Meta" />
<style asp-name="{{ThemeStyleName}}"></style>
<resources type="HeadLink" />
<resources type="HeadScript" />
<resources type="StyleSheet" />
</head>
<body>
<zone name="Header" />
<zone name="Content">
@body
</zone>
<zone name="Footer" />
<resources type="FooterScript" />
</body>
</html>
Guidelines
- Always call
await RenderBodyAsync()before rendering any zone that wraps it, so the body content registers its resources first. - Use
@RenderTitleSegments(Site.SiteName)to render page title segments separated by the site name. - Render resource tags in the correct location:
Meta,HeadLink,HeadScript,StyleSheetin<head>, andFooterScriptbefore</body>.
Shape Tag Helpers
Shapes are the fundamental rendering unit in Orchard Core. Use tag helpers to display and compose shapes.
Display a Shape
<shape type="{{ShapeType}}" />
Display a Shape with Properties
<shape type="{{ShapeType}}" prop-title="@item.Title" prop-content="@item.Content" />
- Prefix shape properties with
prop-to pass data into the shape template.
Display a Dynamic Shape Object
When you have a shape object (e.g., from a zone or shape table), render it with display:
@await DisplayAsync(Model)
@await DisplayAsync(Model.Content)
Named Shapes with Cache
<shape type="{{ShapeType}}" cache-id="{{unique-id}}" cache-expires-after="@TimeSpan.FromMinutes(5)" />
Zone Tag Helper
Zones are named buckets in the layout that collect shapes for rendering.
Render a Zone
<zone name="{{ZoneName}}" />
Render a Zone with Wrapper Content
<zone name="{{ZoneName}}">
<div class="container">
@RenderBody()
</div>
</zone>
Conditional Zone Rendering
Check if a zone has content before rendering its wrapper:
@if (Model.{{ZoneName}} != null)
{
<aside>
<zone name="{{ZoneName}}" />
</aside>
}
Common zone names: Header, Navigation, Content, Sidebar, Footer, AfterContent, BeforeContent.
Link Generation
In Orchard Core views, prefer MVC tag helpers so link generation stays in the Razor template and remains route-aware.
Preferred View Pattern
<a asp-action="Edit" asp-controller="Admin" asp-area="MyModule" asp-route-id="@Model.ContentItemId">
@T["Edit"]
</a>
Guidelines
- Prefer
asp-action,asp-controller, and when neededasp-areainstead of hard-coded application URLs. - Do not use
@Url.Content("~/...")to generate application links in Orchard Core views. - Keep link generation in the view when possible so routes stay explicit and easy to override.
- Continue using normal tag helpers for forms and buttons, such as
<form asp-action="Update" method="post">.
URL Generation in Code
If a URL must be generated outside the view, inject LinkGenerator and pass the current HttpContext so Orchard Core generates the correct route-aware URL.
using Microsoft.AspNetCore.Routing;
public sealed class AdminLinkService
{
private readonly LinkGenerator _linkGenerator;
public AdminLinkService(LinkGenerator linkGenerator)
{
_linkGenerator = linkGenerator;
}
public string? GetEditUrl(HttpContext httpContext, string contentItemId)
{
return _linkGenerator.GetPathByAction(
httpContext,
action: "Edit",
controller: "Admin",
values: new
{
area = "MyModule",
id = contentItemId,
});
}
}
Resource Tag Helpers
Register a Stylesheet
<style asp-name="{{ResourceName}}"></style>
Register a Stylesheet with a CDN Fallback
<style asp-name="{{ResourceName}}" version="{{Version}}" cdn-url="{{CdnUrl}}"></style>
Register a Script at the Foot of the Page
<script asp-name="{{ResourceName}}" at="Foot"></script>
Register a Script at the Head
<script asp-name="{{ResourceName}}" at="Head"></script>
Register an Inline Script
<script at="Foot">
document.addEventListener('DOMContentLoaded', function () {
console.log('Page loaded');
});
</script>
Script Dependencies
<script asp-name="{{ResourceName}}" depends-on="jQuery" at="Foot"></script>
Render All Registered Resources
Place these in the layout to output all resources registered by shapes and modules:
<resources type="Meta" />
<resources type="HeadLink" />
<resources type="HeadScript" />
<resources type="StyleSheet" />
<resources type="FooterScript" />
Resource Positions
| Position | Description |
|---|---|
Head |
Rendered in <head> via <resources type="HeadScript" /> |
Foot |
Rendered before </body> via <resources type="FooterScript" /> |
Media Tag Helper
Render an Image from the Media Library
<img asp-src="@Model.ContentItem.Content.{{PartName}}.{{FieldName}}.Paths[0]" />
Resize an Image
<img asp-src="@imagePath" asp-resize-width="300" />
Resize with Width and Height
<img asp-src="@imagePath" asp-resize-width="800" asp-resize-height="600" />
Resize Modes
<img asp-src="@imagePath" asp-resize-width="400" asp-resize-height="400" asp-resize-mode="Crop" />
| Mode | Description |
|---|---|
Pad |
Resize and pad to fit the target dimensions |
BoxPad |
Pad the image to fit within the bounding box |
Crop |
Resize and crop to fill the target dimensions |
Min |
Resize to the minimum of the target dimensions |
Max |
Resize to the maximum of the target dimensions |
Stretch |
Stretch the image to fill the target dimensions |
Content Tag Helpers
Render a Content Item
<contentitem alias="alias:{{alias}}" display-type="Summary" />
Render a Content Item by Content Item ID
<contentitem content-item-id="@Model.ContentItem.ContentItemId" display-type="Detail" />
Common Display Types
| Display Type | Description |
|---|---|
Detail |
Full detail view |
Summary |
Abbreviated summary view |
SummaryAdmin |
Admin-specific summary |
Menu Tag Helper
Render a Named Menu
<menu alias="alias:main-menu" />
- The
aliasattribute specifies the alias of the menu content item. - The menu renders using the menu shape templates, which can be overridden in your theme.
Caching Tag Helper
Cache a Section of Markup
<cache expires-after="@TimeSpan.FromMinutes(10)">
<p>This content is cached for 10 minutes.</p>
</cache>
Cache with a Vary-By Key
<cache expires-after="@TimeSpan.FromMinutes(5)" vary-by="@Context.Request.Path">
@await DisplayAsync(Model.Content)
</cache>
Cache Attributes
| Attribute | Description |
|---|---|
expires-after |
TimeSpan after which the cache entry expires |
expires-on |
Absolute DateTimeOffset for expiration |
expires-sliding |
Sliding TimeSpan expiration window |
vary-by |
Key to vary the cached output (e.g., per path or query) |
vary-by-user |
When true, caches separately per authenticated user |
Date-Time and Time-Zone Tag Helpers
Render a UTC Date in the Site's Time Zone
<date-time utc="@Model.ContentItem.CreatedUtc" />
Render a Date with a Custom Format
<date-time utc="@Model.ContentItem.PublishedUtc" format="MMMM dd, yyyy" />
Render the Current Time Zone Name
<time-zone />
IOrchardHelper Extensions
Access IOrchardHelper via the Orchard property in Razor views that inherit from OrchardCore.DisplayManagement.Razor.RazorPage<TModel>.
Get a Content Item by ID
@{
var item = await Orchard.GetContentItemByIdAsync("{{contentItemId}}");
}
Get a Content Item by Version ID
@{
var item = await Orchard.GetContentItemByVersionIdAsync("{{contentItemVersionId}}");
}
Query Content Items
@{
var items = await Orchard.QueryContentItemsAsync(query =>
query.Where(index => index.ContentType == "BlogPost" && index.Published));
}
Get Content Items by Content Type
@{
var items = await Orchard.GetRecentContentItemsByContentTypeAsync("BlogPost", 10);
}
Get a Content Item by Alias
@{
var item = await Orchard.GetContentItemByHandleAsync("alias:{{alias}}");
}
Get Site Settings Value
@{
var siteName = Orchard.ConsoleLog(Site.SiteName);
}
Access global site settings via Site:
<p>@Site.SiteName</p>
<p>@Site.BaseUrl</p>
Liquid-to-HTML Rendering
@{
var html = await Orchard.LiquidToHtmlAsync("{{ 'now' | date: '%B %d, %Y' }}");
}
Content Item Display
@{
var shape = await Orchard.DisplayContentItemAsync(contentItem, "Summary");
}
@await DisplayAsync(shape)
Defining a Resource Manifest
Register stylesheets and scripts so they can be referenced by name in Razor views.
Resource Manifest Class
public sealed class ResourceManifest : IResourceManifestProvider
{
public void BuildManifests(IResourceManifestBuilder builder)
{
var manifest = builder.Add();
manifest.DefineStyle("{{ThemeStyleName}}")
.SetUrl("~/{{ModuleOrThemeId}}/css/site.min.css", "~/{{ModuleOrThemeId}}/css/site.css");
manifest.DefineScript("{{ThemeScriptName}}")
.SetUrl("~/{{ModuleOrThemeId}}/js/site.min.js", "~/{{ModuleOrThemeId}}/js/site.js")
.SetPosition("Foot");
}
}
Guidelines
- The first
SetUrlparameter is the minified version; the second is the debug version. - Use
SetPosition("Foot")for scripts that should render before</body>. - Use
SetDependencies("jQuery")to declare script dependencies. - Register the manifest class in
Startup.cs:
public sealed class Startup : StartupBase
{
public override void ConfigureServices(IServiceCollection services)
{
services.AddResourceManifest<ResourceManifest>();
}
}
Recipe Step for Themes
Set the Active Theme via Recipe
{
"steps": [
{
"name": "Themes",
"Site": "{{ThemeId}}",
"Admin": "TheAdmin"
}
]
}