Specify ASP.NET Razor Core Pages Layouts and Partial Views with Headless CMS

This blog post describes a solution that lets the CMS user select a layout to override the default layout and a partial view to render an entry from Contentstack. This solution extends an existing solution for using ASP.NET Razor Pages with the Contentstack SaaS headless CMS.

In a global field common to all Contentstack content types that represent types of pages, implement two select fields: one named Layout to allow the CMS user to select a layout and another named Partial to let them select a partial view. In the list of values for the layout field, add the names of the layout files from which the user must select one (_layout and _alternate in my case) and make the field mandatory. In the list of values for the Partial field, enter the names of the partial views from which the user must select one (partial and alternate in my case), and make the field mandatory. Create corresponding properties in the EntryModelBase class.

using Newtonsoft.Json.Linq;

public class EntryModelBase
{
    public string Title { get; set; }
    public string Layout { get; set; }
    public string Partial { get; set; }
    public JObject Json { get; set; }
}

Move the markup from the index.cshtml file to a partial .cshtml file and replace the remaining contents of that file with the following:

@page  "/get/{contentType}/{entryId}"
@model IndexModel

@{
    if (!String.IsNullOrWhiteSpace(Model.EntryModel.Layout))
    {
        this.Layout = Model.EntryModel.Layout;
    }
}

@await Html.PartialAsync(Model.EntryModel.Partial);

This view generates no markup. This view controls which layout the system invokes. When that layout renders this view, this view invokes the partial view specified by the user and stored in the entry (I added a slick border around it).

Here is an example alternate.cshtml file:

<div style="border: 1px solid black;">
    <h4>This is from the alternate partial view.</h4>
    <div class="text-center">
        <h1 id="heading" class="display-4"></h1>
    </div>
    <pre id="json"></pre>
</div>
<script>
    var json = @(new Microsoft.AspNetCore.Html.HtmlString(Model.EntryModel.Json.ToString()));
    document.getElementById('heading').innerHTML = json.title;
    document.getElementById('json').appendChild(document.createTextNode(JSON.stringify(json, null, 4)));
</script>

In the following screen shot, the user has selected to render the entry with the _alternate layout (also enhanced with a slick border as follows) and the alternate partial view.

<div class="container" style="border: 1px solid black;">
    <main role="main" class="pb-3">
        <h2>This is the alternate view.</h2>
        @RenderBody()
    </main>
</div>

Here is the layout drop-downs in the CMS:

Here is the page with the default layout (_layout) and partial view (partial) selected:

You can take this approach to any level. For example, fields in your groups and modular blocks can let users select additional partials views to apply, passing those fields and blocks as models to the partial views, allowing users to control a component architecture and the data that feeds it.

Update 13.May.2021: ASP.NET Core Web API Prototype, Part I: .NET Web API Server/Client Overview – Deliverystack.net

2 thoughts on “Specify ASP.NET Razor Core Pages Layouts and Partial Views with Headless CMS

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: