All pages
Powered by GitBook
1 of 16

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Models Builder

Modelsbuilder reference

The Models builder is a tool that can generate a complete set of strongly-typed published content models for Umbraco. Models are available in both controllers and views.

  • Introduction

  • Configuration

  • Builder Modes

Templating

Information on configuring Templates (Views) and Partials (Partial Views)

Templating in Umbraco consists of 3 larger concepts, namely Templates (Views) and Partials (Partial Views).

  • Templates are used for the HTML layout of your pages.

  • Partials can be included in your templates for shared functionality across different page templates.

Builder Modes

Modelsbuilder modes

Models Builder can be used in different modes:

  • InMemory models

  • SourceCode models

The mode is indicated by the Umbraco:CMS:ModelsBuilder:ModelsMode key in the configuration (appsettings.json files).

Example

Working with MVC

How to work with MVC templates in Umbraco.

Working with MVC Views and Razor syntax in Umbraco

Using Interfaces

Using interfaces with modelsbuilder

When using compositions, Models Builder generates an interface for the composed model, which enables us to not have to switch back to using Value() for the composed properties.

A common use-case for this is if you have a separate composition for the "SEO properties" Page Title and Page Description.

You would usually use this composition on both your Home and Textpage document types. Since both Home and Textpage will implement the generated ISeoProperties interface, you will still be able to use the simpler models builder syntax (e.g.

View/Razor Examples

Lots of examples of using various techniques to render data in a view

Rendering the raw value of a field from IPublishedContent

Rendering the converted value of a field from IPublishedContent

Templating technology

Umbraco uses ASP.Net MVC Views for implementing templates.

The WebForms (masterpages) and Dynamic Razor approaches to templating are still available in Umbraco version 7 but have been removed in Umbraco version 8.

Working with MVC (views, razor, etc...)

Describes how to work with MVC views, the razor syntax and APIs available. It also describes how to create forms, has some step-by-step guides and other advanced techniques.

Models Builder

A tool that can generate a complete set of strongly-typed published content models for Umbraco. Models are available in controllers, views, anywhere. Runs either from the Umbraco UI, from the command line, or from Visual Studio.

Understand and Extend Models
Using Interfaces
Tips and Tricks

Documentation covering how to use Partial Views. This documentation relates to using native MVC partial views within Umbraco.

ViewComponents

Using MVC Child Actions in Umbraco

Querying

How to query for published data in your Views

Views
See some quick examples here
Partial Views

Tips and Tricks

Cool things you can do with models

It's possible with Razor to define functions for rendering HTML. We can leverage our strongly typed models when doing this, and even provide overloads for different types of models. That will automatically be called for different models using dynamic

@functions
{
  // Declare how to render a news item
  void RenderContent(NewsItem item)
  {
    <div>News! @item.Title</div>
  }

  // Declare how to render a product
  void RenderContent(Product item)
  {
    <div>Product! @product.Name cheap at @product.Price</div>
  }
}

@{
  RenderContent((dynamic) Model);
}

It's not recommended to create a template and doing all the rendering via razor function, but it can be nifty for rendering search results.

A thing that's important to note here is that RenderContent is called from a codeblock, and not as @RenderContent((dynamic) Model); the reason for this is that if you try to use the latter, razor will expect for the function to return something for it to render.

By casting the strongly typed to a dynamic when calling the RenderContent method, you tell C# to do late runtime binding. You also tell it to pick the proper RenderContent implementation depending on the actual Common Language Runtime (CLR) type of the content object. Using dynamic here is OK and will not pollute the rest of the code.

appsettings.json
configuration

Replace InMemoryAuto with one of the valid options: SourceCodeAuto, SourceCodeManual, or InMemoryAuto depending on your preferred mode.

In memory

Corresponds to the InMemoryAuto setting value.

With InMemory models, models are generated and compiled on the fly, in memory, at runtime. They are available in views exclusively.

This is for a setup that exclusively uses the Umbraco backoffice, and do not use custom code such as controllers. Whenever a content type is modified, models are updated without restarting Umbraco (in the same way .cshtml views are recompiled).

Generation can fail for various reasons, in which case Umbraco will run without models (and front-end views fail to render). Umbraco's log file should contain all details about what prevented the generation, but it is probably faster to check the Models Builder dashboard, which should report the last error that was encountered, if any.

Models Builder maintains some files in ~/umbraco/Data/TEMP/InMemoryAuto:

  • models.generated.cs contains the generated models code

  • all.generated.cs contains the compiled code (models merged with non-generated files)

  • models.hash contains a hash code of the content types

  • all.dll.path contains the path to the compiled DLL file containing all the models

  • Compiled/generated.cs{GUID}.dll the dll containing all the generated models

  • models.err contains the last generation error information, if any

The models.hash file is used when Umbraco restarts, to figure out whether models have changed and need to be re-generated. Otherwise, the local models.generated.cs file is reused.

SourceCode Models

Corresponds to the SourceCodeManual and SourceCodeAuto setting values.

With SourceCode models, models are generated in the ~/umbraco/models directory, and that is all. It is then up to you to decide how to compile the models (e.g. by including them in a Visual Studio solution).

Generation can fail for various reasons, in which case no models are generated. Umbraco's log file should contain all details about what prevented the generation, but it is probably faster to check the Models Builder dashboard, which should report the last error that was encountered, if any.

The modelsbuilder works much in the same way whether using SourceCodeManual or SourceCodeAuto. The only real difference between the two are that with SourceCodeManual you must manually trigger the generation of the models from the models builder dashboard, whereas with SourceCodeAuto the models are automatically generated whenever content types change.

API models and Dll Models

These modes are not available in the embedded version of Models Builder. See the full version of ModelsBuilder.

Model.PageTitle
).

However, you won't be able to use the nice models builder syntax on any master template, since a master template needs to be bound to a generic IPublishedContent. So you'd have to resort to the ever-so-slightly clumsier Model.Value("pageTitle") syntax to render these properties. It is possible to solve this issue of master templating, by using partial views, to render the SEO specific properties.

Render with a partial

If you create a partial and change the first line to use the interface name for the model binding, you can use the nice Models Builder syntax when rendering the properties, like this:

You can then render the partial from your Master Template with something like this (assuming the partial is named Metatags.cshtml):

It's important to note though, that this master template will only work for content types that use the Seo Properties composition.

@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage<ISeoProperties>
<title>@Model.PageTitle</title>
<meta name="description" content="@Model.PageDescription">
<head>
    @Html.Partial("Metatags")
</head>
@RenderBody()

Rendering some member data

@Model.Value("bodyContent")
@Model.Value<double>("amount")
@Model.Value<IHtmlString>("bodyContent")
@if(Members.IsLoggedIn()){
    var profile = Members.GetCurrentMemberProfileModel();
    var umbracomember = Members.GetByUsername(profile.UserName);

    <h1>@umbracomember.Name</h1>
    <p>@umbracomember.Value<string>("bio")</p>
}
{
  "Umbraco": {
    "CMS": {
      "ModelsBuilder": {
        "ModelsMode": "InMemoryAuto"
      }
    }
  }
}

Introduction

Modelsbuilder introduction

Models Builder is a tool that can generate a complete set of strongly-typed published content models for Umbraco. By default, a slimmed down version of Models Builder is embedded with the main Umbraco distribution.

Models can be used anywhere that content is retrieved from the content cache, i.e. in MVC views, controllers, etc. In other words, when using the Models Builder, the content cache does not return IPublishedContent objects anymore, but strongly typed models, implementing IPublishedContent.

For each content, media and member type in the Umbraco setup, the generator creates a *.generated.cs file, corresponding to the type. For instance, a document type with a textstring property named Title, and a rich text editor named BodyText will look like this:

Now since this is an automatically generated file, it's a bit messy, the important part is that it has all the properties defined and strongly typed:

public virtual global::Umbraco.Cms.Core.Strings.IHtmlEncodedString BodyText => this.Value<global::Umbraco.Cms.Core.Strings.IHtmlEncodedString>(_publishedValueFallback, "bodyText");

And:

Umbraco's content cache returns these objects natively: No need to map, convert or anything; the following code runs:

If your view inherits from UmbracoViewPage<NewsItem> then the model is the content item itself and the syntax is @Model.Title.

Models Builder respects the content types' inheritance tree, i.e. models inherit from each other if required, and mixins (content type compositions) are represented by interfaces.

Models Builder is a "code-after*_" solution. It only generates code from content types that already exist in Umbraco. It is not a "code-first" solution - code-first is a much more complex question.

And once you are using strongly typed models, there are some that you can do.

Installing

The Models Builder is by default embedded in Umbraco. If you need more complex features than what is provided, you still need to add the full package. However, as of right now the package is not updated to be able to handle NetCore or Umbraco V9.

Check for more details.

Documentation

At the core of the strongly typed models "experience" is the IPublishedModelFactory interface. This interface is part of the Umbraco core codebase. It is responsible for mapping the internal IPublishedContent implementations returned by the content cache, to strongly typed models. There is a default factory shipped with Umbraco and it is possible to replace this by custom implementations. When using the default factory, models do not necessarily need to be generated by Models Builder.

Models Builder is one way to generate models for the default, built-in factory. Models can be generated automatically or straight from the Settings section of the Umbraco backoffice, for more info see .

Configuration

Explanation of how to configure models builder

The following configuration option can be set in the application settings (in the appsettings.json file):

  • Umbraco.CMS.ModelsBuilder.ModelsMode determines how Models Builder generates models. Valid values are:

    • Nothing: Do not generate models.

    • InMemoryAuto(default): Generate models in a dynamic in-memory assembly.

    • SourceCodeManual: Generate models in ~/umbraco/models (but do not compile them) whenever the user clicks the "Generate models" button on the Models Builder dashboard in the Settings section.

    • SourceCodeAuto: Generate models in ~/umbraco/models (but do not compile them) anytime a content type changes.

  • Umbraco.CMS.ModelsBuilder.ModelsNamespace (string, default is Umbraco.Cms.Web.Common.PublishedModels) specifies the generated models' namespace.

  • Umbraco.CMS.ModelsBuilder.FlagOutOfDateModels (bool, default is true) indicates whether out-of-date models (for example after a content type or Data Type has been modified) should be flagged.

  • Umbraco.CMS.ModelsBuilder.ModelsDirectory (string, default is ~/umbraco/models) indicates where to generate models and manage all files. Has to be a virtual directory (starting with ~/) below the website root (see also: AcceptUnsafeModelsDirectory below).

  • Umbraco.CMS.ModelsBuilder.AcceptUnsafeModelsDirectory (bool, default is false) indicates that the directory indicated in ModelsDirectory is allowed to be outside the website root (e.g. ~/../../some/place). Due to this being a potential security risk, it is not allowed by default.

  • Umbraco.CMS.ModelsBuilder.DebugLevel (int, default is zero) indicates the debug level. Set to greater than zero to enable detailed logging. For internal / development use.

Example Configuration

The example below shows an example configuration using the SourceCodeManual mode.

It is recommended to generate models in your development environment only and change the ModelsMode to Nothing for your staging and production environments.

Models Builder Dashboard

Models Builder ships with a dashboard in the Settings section of Umbraco's backoffice. The dashboard does three things:

  • Details on how Models Builder is configured

  • Provides a way to generate models (in SourceCodeManual mode only)

  • Reports the last error (if any) that would have prevented models from being properly generated

Creating Forms

Creating an HTML form to submit data with MVC in Umbraco is possible in a few steps.

If you want to create a Form:

  1. Using view models, views, controllers, and a handy HtmlHelper extension method called BeginUmbracoForm, see the article.

  2. Using Umbraco Forms, see the article.

//------------------------------------------------------------------------------
// <auto-generated>
//   This code was generated by a tool.
//
//    Umbraco.ModelsBuilder.Embedded v15.0.0
//
//   Changes to this file will be lost if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

using System;
using System.Linq.Expressions;
using Umbraco.Cms.Core.Models.PublishedContent;
using Umbraco.Cms.Core.PublishedCache;
using Umbraco.Cms.Infrastructure.ModelsBuilder;
using Umbraco.Cms.Core;
using Umbraco.Extensions;

namespace Umbraco.Cms.Web.Common.PublishedModels
{
/// <summary>NewsItem</summary>
[PublishedModel("newsItem")]
public partial class NewsItem : PublishedContentModel
{
  // helpers
#pragma warning disable 0109 // new is redundant
  [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Umbraco.ModelsBuilder.Embedded", "15.0.0")]
  public new const string ModelTypeAlias = "newsItem";
  [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Umbraco.ModelsBuilder.Embedded", "15.0.0")]
  public new const PublishedItemType ModelItemType = PublishedItemType.Content;
  [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Umbraco.ModelsBuilder.Embedded", "15.0.0")]
  [return: global::System.Diagnostics.CodeAnalysis.MaybeNull]
  public new static IPublishedContentType GetModelContentType(IPublishedContentTypeCache contentTypeCache)
  	=> PublishedModelUtility.GetModelContentType(contentTypeCache, ModelItemType, ModelTypeAlias);
  [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Umbraco.ModelsBuilder.Embedded", "15.0.0")]
  [return: global::System.Diagnostics.CodeAnalysis.MaybeNull]
  public static IPublishedPropertyType GetModelPropertyType<TValue>(IPublishedContentTypeCache contentTypeCache, Expression<Func<Page, TValue>> selector)
    => PublishedModelUtility.GetModelPropertyType(GetModelContentType(contentTypeCache), selector);
#pragma warning restore 0109

  private IPublishedValueFallback _publishedValueFallback;

  // ctor
  public NewsItem(IPublishedContent content, IPublishedValueFallback publishedValueFallback)
    : base(content, publishedValueFallback)
  {
    _publishedValueFallback = publishedValueFallback;
  }

  // properties

  ///<summary>
  /// BodyText
  ///</summary>
  [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Umbraco.ModelsBuilder.Embedded", "15.0.0")]
  [global::System.Diagnostics.CodeAnalysis.MaybeNull]
  [ImplementPropertyType("bodyText")]
  public virtual global::Umbraco.Cms.Core.Strings.IHtmlEncodedString BodyText => this.Value<global::Umbraco.Cms.Core.Strings.IHtmlEncodedString>(_publishedValueFallback, "bodyText");

  ///<summary>
  /// Title
  ///</summary>
  [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Umbraco.ModelsBuilder.Embedded", "15.0.0")]
  [global::System.Diagnostics.CodeAnalysis.MaybeNull]
  [ImplementPropertyType("title")]
  public virtual string Title => this.Value<string>(_publishedValueFallback, "title");
  }
}
public virtual string Title => this.Value<string>(_publishedValueFallback, "title");
Creating Forms
Umbraco Forms Documentation
cool things
the official releases on the Models Builder GitHub repository
builder modes
Models Builder Dashboard
@using ContentModels = Umbraco.Cms.Web.Common.PublishedModels;
@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage<ContentModels.NewsItem>
<h1>@Model.Title</h1>
<p>@Model.BodyText</p>
{
  "$schema": "https://json.schemastore.org/appsettings.json",
  "Umbraco": {
    "CMS": {
      "ModelsBuilder": {
        "ModelsMode": "SourceCodeManual"
      }
    }
  }
}

Working with MVC Views in Umbraco

Working with MVC Views and Razor syntax in Umbraco

Properties available in Views

All Umbraco views inherit from Umbraco.Cms.Web.Common.Views.UmbracoViewPage<ContentModels.NameOfYourDocType> along with the using statement @using ContentModels = Umbraco.Cms.Web.Common.PublishedModels;. This exposes many properties that are available in razor. The properties on the Document Type can be accessed in a number of ways:

  • @Model (of type Umbraco.Web.Mvc.ContentModel) -> the model for the view which contains the standard list of IPublishedContent properties but also gives you access to the typed current page (of type whatever type you have added in the angled brackets).

  • @Umbraco (of type UmbracoHelper) -> contains many helpful methods, from rendering fields to retrieving content based on an Id and tons of other helpful methods.

  • @Html (of type HtmlHelper) -> the same HtmlHelper you know and love from Microsoft but we've added a bunch of handy extension methods like @Html.BeginUmbracoForm

  • @UmbracoContext (of type Umbraco.Cms.Web.Common.UmbracoContext)

Rendering a field in a strongly typed view

This is probably the most used method which renders the contents of a field using the alias of the content item.

If you're using the method from within a partial view then be aware that you will need to inherit the context so the method knows which type to get the desired value from. You'd do this at the top of partial view and so strongly typed properties can then be accessed in the partial view. For instance you can pass "HomePage" like this:

You will also need to pass the "Context" to the @Model.Value() method if you're looping over a selection like this where we pass the "item" variable.

Looping over a selection works in a similar way. If you have a property that contains, for instance, an IEnumberable collection, you can access the individual items using a foreach loop. Below illustrates how you might do that using "item" as a variable.

If you want to convert a type and it's possible, you can do that by typing a variable and assigning the value from your property to it. This could look like the example below.

In this example, we are looping through a list of items with the custom made type TeamMember assigned. This means we are able to access the strongly typed properties on the TeamMember item.

Accessing Member data

IMemberManager is the gateway to everything related to members when templating your site.

Models Builder

Models Builder allows you to use strongly typed models in your views. Properties created on your document types can be accessed with this syntax:

When Models Builder resolve your properties it will also try to use value converters to convert the values of your data into more convenient models. This allows you to access nested objects as strong types instead of having to rely on dynamics and risking having a lot of potential errors when working with these.

Macros

**Are you looking for documentation about Macros and/or Partial View Macros?

Macros and Partial View Macros have been removed with the release of Umbraco 14.

We recommend using Partial Views or Blocks in the Rich Text Editor as a replacement.

Learn more about the decision for remove Macros in the official announcement: Breaking change: Macros will be removed in Umbraco 14.

See UmbracoHelper Documentation
UmbracoHelper Documentation
IMemberManager Documentation
Models Builder documentation
@Model.Value("bodyContent")
@inherits UmbracoViewPage<HomePage>
...
@Model.Value("title")
@{
    var collection = Model.ItemList;
}

<ul>
    @foreach(var item in collection)
    {
        <p>@item.Name</p>
    }
</ul>
@foreach (TeamMember person in Model.TeamMembers)
{
    <a href="@person.Url()">
       <p>@person.Name</p>
    </a>
}
@using Umbraco.Cms.Core.Security;
@inject IMemberManager _memberManager;

@if(_memberManager.IsLoggedIn())
{
    <p>A Member is logged in</p>
}
else
{
    <p>No member is logged in</p>
}
@Model.BodyText

Understand and Extend

Understanding and Extending ModelsBuilder in Umbraco

Umbraco’s Models Builder automatically generates strongly typed models for content types, allowing developers to work with Umbraco data in a structured and efficient manner. This article explains how models are generated, how composition and inheritance work, and best practices for extending models without causing issues.

Models Generation Process

Models Builder generates each content type as a partial class. For example, a content type named TextPage results in a TextPage.generated.cs file with a structure like this:

In the above code:

  • The model includes a constructor and static helpers to fetch the content type (PublishedContentType) and property type (PublishedPropertyType).

  • The most important part is the property definition (Header), which retrieves values from Umbraco.

You can use helper methods to access content and property types:

Composition and Inheritance

Composition

Umbraco content types can be composed of multiple other content types. Unlike traditional C# inheritance, Umbraco allows a content type to inherit properties from multiple sources.

In Umbraco v14, the traditional .NET Inheritance feature has been removed. Instead, properties are inherited through Composition, allowing for greater flexibility in managing content types.

For example, a TextPage might be composed of:

  • MetaInfo content type (inherits Author and Keywords properties).

  • PageInfo content type (inherits Title and MainImage properties).

Each content type in a composition is generated both as a class and as an interface. The MetaInfo content type would be generated as:

And the TextPage model would be generated as:

Inheritance

In addition to composition, earlier versions of Umbraco allowed content types to have a parent-child relationship. In the Umbraco backoffice, a content type appears underneath its parent.

The option to add child content types in the backoffice was removed in v14. Migrated sites may still have the child content types set up. New content types can be inherited through Composition.

This type of inheritance is treated differently since the content type is always composed of its parent. The child content type inherits directly (as in C# inheritance) from the parent class.

If AboutPage is a child of TextPage, its generated model would inherit directly from TextPage:

Extending Models

Since models are partial classes, developers can extend them by adding additional properties.

For Example:

Models Builder does not recognize custom partial classes during regeneration. If your custom class conflicts with the generated class (e.g., overriding a constructor), it will cause compilation errors.

Overloaded constructors will not be used because models are always instantiated using the default constructor.

For more complex customizations, use the full version of .

Custom Model Generation with IModelsGenerator

From Umbraco 11.4, you can implement the IModelsGenerator interface to customize how models are generated. This allows you to replace Umbraco’s default implementation using dependency injection:

The interface can be accessed via Infrastructure.ModelsBuilder.Building.ModelsGenerator.

Best Practices for Extending Models

Extending models should be used to add stateless, local features to models. It should not be used to transform content models into view models or manage trees of content.

Good practices

A customer has "posts" that has two "release date" properties. One is a true date picker property and is used to specify an actual date and to order the posts. The other is a string that is used to specify dates such as "Summer 2015" or "Q1 2016". Alongside the title of the post, the customer wants to display the text date, if present, else the actual date. If none of those are present, the Umbraco update date should be used. Keep in mind that each view can contain code to deal with the situation, but it is much more efficient to extend the Post model:

Simplified view:

Bad practices

Because, by default, the content object is passed to views, one can be tempted to add view-related properties to the model. Some properties that do not belong to a content model would be:

  • A HomePage property that retrieves the "home page" content item.

  • A Menu property that lists navigation items.

Generally speaking, anything that is tied to the current request, or that depends on more than the modeled content, is a bad idea. There are much cleaner solutions, such as using true view model classes that would be populated by a true controller and look like:

One can also extend Umbraco's views to provide a special view helper that gives access to important elements of the website:

Ugly practices

The model's scope and lifecycle are unspecified. It may exist only for your request or be cached and shared across all requests.

The code has a major issue: the TextPage model caches a HomePageDocument model that will not update when the home page is re-published.

As a rule of thumb, models should never reference and cache other models.

Querying & Traversal

This section will describe how you can render content from other nodes besides the current page in your MVC Views

Querying for content and media by id

The easiest way to get some content by Id is to use the following syntax (where 1234 is the content id you'd like to query for):

You can also query for multiple content items using multiple ids:

This syntax will support an unlimited number of Ids passed to the method.

You can also retrieve content using the Guid Id. In the example "ca4249ed-2b23-4337-b522-63cabe5587d1" is the key of the content.

You can also pass a to retrieve the content.

The same query structures apply to media:

Traversing

All of these extension methods are available on Umbraco.Core.Models.IPublishedContent so you can have strongly typed access to all of them with intellisense for both content and media. The following methods return IEnumerable<IPublishedContent>

Additionally there are other methods that will return a single IPublishedContent

Complex querying (Where)

With the IPublishedContent model we support strongly typed LINQ queries out of the box so you will have intellisense for that.

Some examples

Where children are visible

Traverse for sitemap

The two examples below have not been verified for Umbraco 9 and 10 yet.

therefore they might not work on the latest versions of Umbraco.

Content sub menu

Complex query

With the strongly typed IPublishedContent you can do complex queries.

Using View Components in Umbraco

In the previous versions of MVC, we used Child Actions to build reusable components/widgets consisting of both Razor markup and backend logic. The backend logic was implemented as a controller action and marked with a [ChildActionOnly] attribute. Child Actions are no longer supported in ASP.NET Core MVC. Instead, we will use the View Component feature.

View Component Overview

View components replace the traditional Controller (SurfaceController)/Partial View relationship and instead offers a modular approach of separating your views in to several smaller units. View Components are self-contained objects that consistently render HTML from a Razor view.

View components are:

/// <summary>TextPage</summary>
[PublishedModel("textPage")]
public partial class TextPage : PublishedContentModel
{
  //static helpers
  public new const string ModelTypeAlias = "textPage";

  public new const PublishedItemType ModelItemType = PublishedItemType.Content;

  public new static IPublishedContentType GetModelContentType(IPublishedContentTypeCache contentTypeCache)
  	=> PublishedModelUtility.GetModelContentType(contentTypeCache, ModelItemType, ModelTypeAlias);

  public static IPublishedPropertyType GetModelPropertyType<TValue>(IPublishedContentTypeCache contentTypeCache, Expression<Func<Page, TValue>> selector)
    => PublishedModelUtility.GetModelPropertyType(GetModelContentType(contentTypeCache), selector);

  private IPublishedValueFallback _publishedValueFallback;

  //constructor
  public TextPage(IPublishedContent content, IPublishedValueFallback publishedValueFallback)
    : base(content, publishedValueFallback)
  {
    _publishedValueFallback = publishedValueFallback;
  }

  // properties

  ///<summary>
  /// Header
  ///</summary>
  [ImplementPropertyType("header")]
  public virtual string Header => this.Value<string>(_publishedValueFallback, "header");
}
// to return IPublishedContent
@Umbraco.Content(1234)
// to return the strongly typed (IEnumerable<Umbraco.Core.Models.IPublishedContent>) collection
@Umbraco.Content(1234, 4321, 1111, 2222)
Models Builder
Udi

Generated from a C# class

  • Derived from the base class ViewComponent and

  • Associated with a Razor file (*.cshtml) to generate markup.

  • View components are similar to partial views but they are much more powerful compared to the partial views. View components do not use model binding, instead they work with the data provided when calling it.

    View Components can be implemented in any part of the web application. There are some possibilities to duplicate code like Header, Navigation Pane, Login Panel, Menu, Shopping Cart, Footer, BlockList Items and so on. View Components behave like a web part containing both business logic and UI design. This is because they create a package which can be reused in multiple parts of the web application.

    A view component code consists of two parts:

    • The View Component class derived from the ViewComponent class:

    • Returns a Task object as IViewComponentResult:

    Create a class for a ViewComponent

    In this example, let's create a ViewComponent for a Product List and render it on the HomePage of the website.

    Create a folder named ProductView. In this folder, create a new class named ProductViewViewComponent.cs as below:

    Create a View for ViewComponent

    In Views folder, create new folders at Views\Shared\Components\ProductView. In the ProductView folder, create a new file named Default.cshtml as below:

    UmbracoHelper in a ViewComponent

    Adding the following declaration will give access to the UmbracoHelper object inside the ViewComponent View

    Invoking a View Component

    You can invoke a ViewComponent from anywhere (even from within a Controller or another ViewComponent). Since this is our Product List, we want it rendered on the Home page - so we’ll invoke it from our HomePage.cshtml file using:

    You can read about different ways of invoking your view component in the View components in ASP.NET Core section of the Microsoft Documentation.view=aspnetcore-5.0)

    View Component Locations

    By default, the framework searches for the Component View path in the following areas:

    • /Views/{Controller Name Folder}/Components/{View Component Name Folder}/{View Name}

    • /Views/Shared/Components/{View Component Name Folder}/{View Name}

    var contentType = TextPage.GetModelContentType(); // is a PublishedContentType
    var propertyType = TextPage.GetModelPropertyType(x => x.Header); // is a PublishedPropertyType
    // The composition interface
    public partial interface IMetaInfo : IPublishedContent
    {
      public string Author { get; }
      public IEnumerable<string> Keywords { get; }
    }
    
    // The composition class
    public partial class MetaInfo : PublishedContentModel
    {
      // the "static mixin getter" for the property
      public static string GetAuthor(IMetaInfo that)
      {
        return that.GetPropertyValue<string>("author");
      }
    
      public string Author { get { return MetaInfo.GetAuthor(this, _publishedValueFallback); } }
    }
    public partial class TextPage : PublishedContentModel, IMetaInfo
    {
      // get the property value from the "static mixin getter"
      public string Author { get { return MetaInfo.GetAuthor(this, _publishedValueFallback); } }
    }
    // Note: Inherits from TextPage
    public partial class AboutPage : TextPage
    {
      ...
    }
    public partial class TextPage
    {
        public string WrappedHeader => $"[{Header}]";
    }
        public partial class Post
        {
            public string DisplayDate
            {
                get
                {
                    if(!TextDate.IsNullOrWhiteSpace())
                    {
                        return TextDate;
                    }
    
                    if (ActualDate != default)
                    {
                        return ActualDate.ToString();
                    }
    
                    return UpdateDate.ToString();
                }
            }
        }
    <div class="title">
      <div class="title-text">@Model.Title</div>
      <div class="title-date">@Model.DisplayDate</div>
    </div>
    public class TextPageViewModel
    {
      public TextPage Content; // The content model
      public HomePage HomePage; // The home page content model
      public IEnumerable<MenuItem> Menu; // The menu content models
    }
    <a href="@MySite.HomePage.Url">@MySite.HomePage.Title</a>
    private HomePageDocument _homePage;
    public HomePageDocument HomePage
    {
        get
        {
            if (_homePage is null)
            {
                _homePage = this.AncestorOrSelf<HomePageDocument>(1);
            }
            return _homePage;
        }
    }
    // to return the Umbraco.Core.Models.IPublishedContent
    @Umbraco.Content(Guid.Parse("ca4249ed-2b23-4337-b522-63cabe5587d1"))
    // to return the Umbraco.Core.Models.IPublishedContent
    @Umbraco.Content(Udi.Create("document", Guid.Parse("ca4249ed-2b23-4337-b522-63cabe5587d1")))
    @Umbraco.Media(9999)
    @Umbraco.Media(9999,8888,7777)
    @Umbraco.Media(9999)
    @Umbraco.Media(9999,8888,7777)
    @Umbraco.Content(Guid.Parse("ca4249ed-2b23-4337-b522-63cabe5587d1"))
    @Umbraco.Content(Udi.Create("media", Guid.Parse("ca4249ed-2b23-4337-b522-63cabe5587d1")))
    Children() // this is the same as using the Children property on the content item.
    Ancestors()
    Ancestors(int level)
    Ancestors(string nodeTypeAlias)
    AncestorsOrSelf()
    AncestorsOrSelf(int level)
    AncestorsOrSelf(string nodeTypeAlias)
    Descendants()
    Descendants(int level)
    Descendants(string nodeTypeAlias)
    DescendantsOrSelf()
    DescendantsOrSelf(int level)
    DescendantsOrSelf(string nodeTypeAlias)
    Siblings()
    SiblingsAndSelf()
    Ancestor()
    AncestorOrSelf()
    AncestorOrSelf(int level)
    AncestorOrSelf(string nodeTypeAlias)
    AncestorOrSelf(Func<IPublishedContent, bool> func)
    @Model.Children().Where(x => x.IsVisible())
    var items = @Model.Children().Where(x => x.IsVisible() && x.Level <= 4)
    @Model.AncestorOrSelf(1).Children().Where(x => x.DocumentTypeAlias == "DatatypesFolder").First().Children()
    // This example gets the top level ancestor for the current node, and then gets
    // the first node found that contains "1173" in the array of comma delimited
    // values found in a property called 'selectedNodes'.
    
    var result = @Model.Ancestors().OrderBy(x => x.Level)
        .Single()
        .Descendants()
        .FirstOrDefault(x => x.GetPropertyValue("selectedNodes", "").Split(',').Contains("1173"));
    [ViewComponent(Name = "Employee")]
    public class EmployeeViewComponent : ViewComponent
    {}
    public IViewComponentResult Invoke()
    {
        return Content("Hi I'm an Employee Component");
    }
    using System.Collections.Generic;
    using Microsoft.AspNetCore.Mvc;
    
    namespace Umbraco.Docs.Samples.Web.Components.ProductView;
    
    public class ProductViewViewComponent : ViewComponent
    {
        public IViewComponentResult Invoke()
        {
            List<string> products = new List<string>() {
                "Product 1", "Product 2", "Product 3", "Product 4", "Product 5"
            };
    
            return View(products);
        }
    }
    <h1> Welcome to your Home Page </h1>
    <h2>Products List</h2>
    <ul>
        @foreach (var product in Model)
        {
            <li>@product</li>
        }
    </ul>
    @inject Umbraco.Cms.Web.Common.UmbracoHelper Umbraco
     @(await Component.InvokeAsync("ProductView"))

    Using MVC Partial Views in Umbraco

    This section will show you how to use MVC Partial Views in Umbraco.

    Please note, this is documentation relating to the use of native MVC partial views

    Partial views allow you to reuse components between your views (templates).

    View Locations

    The locations to store Partial Views when rendering in the Umbraco pipeline is:

    The standard MVC partial view locations will also work:

    The ~/Views/Render location is valid because the controller that performs the rendering in the Umbraco codebase is the: Umbraco.Cms.Web.Common.Controllers.RenderController

    If however you are and specifying your own controller to do the execution, then your partial view location can also be:

    Example

    A quick example of a content item that has a template that renders out a partial view template for each of its child documents:

    The MVC template markup for the document:

    The partial view (located at: ~/Views/Partials/ChildItem.cshtml)

    Strongly typed Partial Views

    Normally you would create a partial view by using the @model MyModel syntax. However, inside of Umbraco you will probably want to have access to the handy properties available on your normal Umbraco views like the Umbraco helper: @Umbraco and the Umbraco context: @UmbracoContext. The good news is that this is possible. Instead of using the @model MyModel syntax, you need to inherit from the correct view class, so do this instead:

    By inheriting from this view, you'll have instant access to those handy properties and have your view created with a strongly typed custom model.

    Another case you might have is that you want your Partial View to be strongly typed with the same model type (IPublishedContent) as a normal template if you are passing around instances of IPublishedContent. To do this, have your partial view inherit from Umbraco.Cms.Web.Common.Views.UmbracoViewPage (like your normal templates). When you render your partial, a neat trick is that you can pass it an instance of IPublishedContent. For example:

    Caching

    You don't normally need to cache the output of Partial views, like you don't normally need to cache the output of User Controls. However, there are times when this is necessary and so we provide caching output of partial views. This is done by using an HtmlHelper extension method:

    The above will cache the output of your partial view for one hour when not running Umbraco in debug mode. Additionally, there are a few optional parameters you can specify to this method. Here is the full method signature:

    So you can specify to cache by member and/or by page and also specify additional view data to your partial view. * However*, if your view data is dynamic (meaning it could change per page request) the cached output will still be returned. This same principle applies if the model you are passing in is dynamic. Please be aware of this: if you have a different model or viewData for any page request, the result will be the cached result of the first execution. If this is not desired you can generate your own cache key to differentiate cache instances using the contextualKeyBuilder parameter

    To create multiple versions based on one or more viewData parameters you can do something like this:

    Or using a custom helper function:

    Or even based on a property on the Model (though if Model is the current page then cacheByPage should be used instead):

    Regardless of the complexity here the contextualKeyBuilder function needs to return a single string value.

    Caching is only enabled when your application has debug="false". When debug="true" caching is disabled. Also, the cache of all CachedPartials is emptied on Umbraco publish events.

    Hijacking an Umbraco route
    ~/Views/Partials
    ~/Views/Shared
    ~/Views/Render
    ~/Views/{YourControllerName}
    @inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage
    @{
        Layout = null;
    }
    
    <html>
    <body>
    @foreach(var page in Model.Children().Where(x => x.IsVisible()))
        {
            <div>
                @Html.Partial("ChildItem", page)
            </div>
        }
    </body>
    </html>
    @model IPublishedContent
    <strong>@Model.Name</strong>
    @inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage<MyModel>
    @foreach(var child in Model.Children())
    {
        @Html.Partial("MyPartialName", child)
    }
    @await Html.CachedPartialAsync("ChildItem", page, TimeSpan.FromHours(1))
    Task<IHtmlContent?> CachedPartialAsync(
            this IHtmlHelper htmlHelper,
            string partialViewName,
            object model,
            TimeSpan cacheTimeout,
            bool cacheByPage = false,
            bool cacheByMember = false,
            ViewDataDictionary? viewData = null,
            Func<object, ViewDataDictionary?, string>? contextualKeyBuilder = null)
    @await Html.CachedPartialAsync("ChildItem", Model, TimeSpan.FromHours(1), true, false, new ViewDataDictionary(ViewData)
    {
        { "year", Context.Request.Query["year"] }
    }, (model, viewData) => viewData?["year"] + viewData?["Parameter2"]?.ToString() )
    @functions{
        private static Func<object, ViewDataDictionary?, string>? CacheBy(params string[] keys)
        {
            return (model, viewData) => String.Join("", keys.Select(s => viewData?[s]?.ToString() ?? string.Empty));
        }
    }
    
    @await Html.CachedPartialAsync("MediaGallery", Model, TimeSpan.FromHours(1), true, false, new ViewDataDictionary(ViewData)
            {
                { "year", Context.Request.Query["year"] }
            }, CacheBy("year", "Parameter2"))
     @await Html.CachedPartialAsync("MediaGallery", Model, TimeSpan.FromHours(1), true, false, new ViewDataDictionary(ViewData) { },
     (model, viewData) => (model is IPublishedContent pc ? pc.Name : null) ?? string.Empty)