Skip to main content

umbraco-templating

Server-rendered Umbraco 17 front-end: Razor templates and layouts, partial views, view components, route hijacking (RenderController + view model) and surface-controller form posts. Use when asked to "create a template", "write a Razor view for a document type", "render a property", "add a partial view", "build a view component" or reusable widget, "hijack a route", "add a custom controller for a document type", "pass a custom view model to a template", "server-side paging on a page", "handle a form post", "use BeginUmbracoForm", "create a surface controller", or "cache a partial" — or when a Razor view won't compile after copying a docs snippet (`IHtmlString`, `Html.Partial`, `Members.`), or a page 404s after adding a template. SKIP: headless / Content Delivery API front-ends; backoffice extensions and Management API controllers; custom routes outside the content tree or `IContentFinder`; ModelsBuilder configuration; member login/registration; non-Umbraco projects or Umbraco < 17.

Informations de source

Dépôt
umbraco/Umbraco-CMS-Implementation-Skills
Dernière activité de la source
15 octobre 2026 à 11:21
Langue détectée de SKILL.md
anglais
Étoiles
7
Forks
8

Options d'installation

Le prompt qui vérifie d'abord la source est sélectionné par défaut. Vous pouvez passer à une commande directe ou télécharger une copie locale.

Vérifiez les fichiers source

Lisez SKILL.md et les fichiers associés affichés par SkillsMP avant de décider de l'installer.

Explorateur de fichiers
39 fichiers

Affichage de SKILL.md

SKILL.md
Instructions source · Aperçu en lecture seule
name
umbraco-templating
description
Server-rendered Umbraco 17 front-end: Razor templates and layouts, partial views, view components, route hijacking (RenderController + view model) and surface-controller form posts. Use when asked to "create a template", "write a Razor view for a document type", "render a property", "add a partial view", "build a view component" or reusable widget, "hijack a route", "add a custom controller for a document type", "pass a custom view model to a template", "server-side paging on a page", "handle a form post", "use BeginUmbracoForm", "create a surface controller", or "cache a partial" — or when a Razor view won't compile after copying a docs snippet (`IHtmlString`, `Html.Partial`, `Members.`), or a page 404s after adding a template. SKIP: headless / Content Delivery API front-ends; backoffice extensions and Management API controllers; custom routes outside the content tree or `IContentFinder`; ModelsBuilder configuration; member login/registration; non-Umbraco projects or Umbraco < 17.
# Templating Umbraco renders every content page through ASP.NET Core MVC: a request is matched to a content node, routed to a controller (Umbraco's `RenderController` unless you hijack it), and rendered by the node's Template, a Razor view. ## Pick the building block | Need | Use | Reference | |---|---|---| | Markup for a Document Type's pages, shared page shell | Template + master layout | [views-and-partials.md](references/views-and-partials.md) | | Reusable markup that only formats the model it's given | Partial view | [views-and-partials.md](references/views-and-partials.md) | | Reusable widget with its own logic or injected services | View component | [view-components.md](references/view-components.md) | | Page needs data that isn't on the node (external API, paging, per-request logic), or a different view per template | Route hijacking: `RenderController` + view model | [route-hijacking.md](references/route-hijacking.md) | | Accept a form POST from a content page | Surface controller | [surface-controllers.md](references/surface-controllers.md) | | JSON / REST endpoint | Not a templating concern: plain ASP.NET Core controller | *Other controller types* in [surface-controllers.md](references/surface-controllers.md) | **Before writing any code, open the reference for every block you use and start from its asset.** The Umbraco 17 traps that break these pages are covered only there. For example, a hijacked `Index` overload throws `AmbiguousMatchException`, and an `*Async` surface action name doesn't route. Code written from this page alone will hit them. ### How to decide Use the lightest block that does the job: template → partial → view component → hijacked controller. Querying other content doesn't need a hijack: a template or view component can do it. A single page often combines several blocks: [`assets/productPage.cshtml`](assets/productPage.cshtml) is a hijacked template that invokes a view component and renders a form partial. A new template renders only once it's registered in Umbraco and assigned to the Document Type, otherwise the page 404s: see step 3 of [views-and-partials.md](references/views-and-partials.md). Finish every building block with a build and a request to a page that exercises it. Check `Umbraco:CMS:ModelsBuilder:ModelsMode` first: - **`Nothing` or `SourceCode*`:** build with `dotnet build -p:RazorCompileOnBuild=true`. The stock Umbraco csproj sets `RazorCompileOnBuild=false`, so a plain `dotnet build` never compiles a view and passes even when they're broken. - **`InMemoryAuto` (Umbraco's default):** the generated models exist only at runtime, so that build fails with CS0246 on a healthy site. A plain `dotnet build` plus the page request is the check. Don't change the user's `ModelsMode` or rewrite their views to make the Razor build pass. If no runnable project is available, say so rather than claiming it works. ## Version compatibility Targets **Umbraco 17**. The `assets/` compile and render on `Umbraco.Cms` 17.5.3. On Umbraco 18, `PublishedContentWrapped` takes only `(IPublishedContent)`, so drop the fallback argument from the view model. Several snippets on the Umbraco 17 docs pages are v8-era and **do not compile or run** on 17. References whose docs pages have broken snippets list them under *Docs corrections*. Trust the assets over the docs where they disagree. ## Best practices - **Views render, they don't fetch.** No `IContentService`/`IMediaService` in a view. Move logic into a view component or a hijacked controller. For performance traps (deep traversal, repeated `Root()`), see the sibling skill `umbraco-common-pitfalls`. - **Async rendering only:** `<partial>`, `await Html.PartialAsync`, `await Component.InvokeAsync`. Never `Html.Partial`/`Html.RenderPartial`, which are sync-over-async and can deadlock (analyzer MVC1000). - **Typed values.** Use `@(Model.Value<T>("alias"))`, or the generated ModelsBuilder property. The `@(...)` is required: in a bare `@Model.Value<T>(...)` Razor reads `<T>` as an HTML tag (CS1503). Rich text converts to `IHtmlEncodedString`, so render it directly. Never `Html.Raw` an editor string. - **Keep the master layout generically typed** (`UmbracoViewPage` or a shared interface, not `UmbracoViewPage<Home>`), or a hijacked page with a custom view model will throw when the layout binds. ## Validation Objective assertions live in [`evals/evals.json`](evals/evals.json); run them with `umbraco-skill-evaluator`. Every asset is **Asserted** by the runtime gate (`examples/render-pipeline/`, blank host): the hijacked route, query binding, property fallback, the view component and both form-post paths are checked over HTTP.
Voir sur GitHub