How Layout Models Work in .NET

Layout Models in Agility CMS allow developers to differentiate the styles of certain types of layouts, and also define where in the layout editors can add and edit Components (functional components of the layout that editors can control).

Depending on your scenario, some sites may only use a single layout model and re-use it across the site, while other sites may have multiple moedls to allow for more flexible layouts.

What is in a Layout Model?

When editors create layouts in Agility CMS, they must select which layout model they'd like to use.

A Layout Model consists of a Name and Zones.

The Name should represent what the editor can expect from using the Layout Model. For example, a site may have templates named One Column LayoutTwo Column Layout, or Blog Layout.

A Zone is an area defined in the Layout Model where an editor can add, edit, or remove components. A Layout Model can have one or many Zones.

An Example

In the agilitycms-dotnet-starter site, the Name of the Layout Model is used to find the corresponding .cshtml file that matches the same name. If a match is found, that component will be dynamically imported and rendered for you.

For example, if a Layout Model has the name of Main Template in the CMS, while the page is being rendered, it will look for ./Views/PageTemplates/MainTemplate.cshtml.

In MainTemplate.cshtml:


<!DOCTYPE html>
<html lang="en">

<head>
    <noscript id="render-onload">
        <link rel="stylesheet" href="~/css/output.css" />
        <link href="~/css/fontawesome/all.min.css" rel="stylesheet">
        <link href="~/css/fontawesome/brands.min.css" rel="stylesheet">
        <link href="~/css/fontawesome/solid.min.css" rel="stylesheet">
        <link href="~/css/fontawesome/fontawesome.min.css" rel="stylesheet">
        <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;900&display=swap" rel="stylesheet" />
    </noscript>
    <script>
        var renderOnLoad = function () {
            var e = document.getElementById('render-onload');
            var n = document.createElement('div');
            n.innerHTML = e.textContent;
            document.body.appendChild(n);
            e.parentElement.removeChild(e);
        };
        if (window.requestAnimationFrame) {
            window.requestAnimationFrame(function() { window.setTimeout(renderOnLoad, 0) });
        } else {
            window.addEventListener('load', renderOnLoad);
        }
    </script>
    @await RenderSectionAsync("SEO")
</head>

<body>
    <div id="site-wrapper">
        <div id="site">
            @await Component.InvokeAsync("PreviewBar")
            <div class="flex flex-col min-h-screen">
                @await RenderSectionAsync("TopZone")
                <main class="flex-grow">
                    @await RenderSectionAsync("MainContentZone")
                </main>
                @await Component.InvokeAsync("SiteFooter")
            </div>
        </div>
    </div>
</body>
</html>

In AgilityPage.cshtml:

The AgilityPage will use this method to get the current Template of the rendered Page.

Layout = PageHelpers.GetPageTemplatePath(Model.PageResponse.TemplateName);