Episode 5 - Part 1

Umbraco 13 Tutorial - Episode 5 Part 1 - Block Grid Navigation

Code

package.manifest

{
	"name": "BlockGridPreviews",
	"version": "1.0.0",
	"allowPackageTelemetery": false
}

package.manifest

navigationgroup.html

<style>

    button {
        position: relative;
        display: flex;
        width: 100%;
        height: 100%;
        cursor: pointer;
        color: black;
        background-color: transparent;
        text-align: left;
        padding: 0;
        user-select: none;
        border: none;
        transition: border-color 120ms, background-color 120ms;
        max-height: 80vh;
        overflow: hidden;
    }

    .hidden-marker-outer {
        width: 90px;
        height: 30px;
        background-color: red;
        color: white;
        z-index: 1;
        text-align: center;
        align-content: center;
        vertical-align: middle;
        position: absolute;
        top: 0px;
        left: 0px;
        border-radius: 0 0 10px 0;
    }

        .hidden-marker-outer span {
            padding-top: 6px;
            display: block;
        }

    .nav-group-container {
        text-align: left;
        margin-top: 30px;
        padding-right: 10px;
    }

    ul li {
        margin-bottom: 10px;
    }

    strong {
        margin-bottom: 5px;
    }

</style>

<button type="button" ng-click="block.edit()" ng-focus="block.focus">
    <div class="nav-group-container">
        <p>
            <strong>{{block.data.title}}</strong>
            <span ng-if="block.data.link">{{block.data.link[0].url}}</span>
        </p>

        <ul>
            <li ng-if="block.data.childLinks" ng-repeat="(key, value) in block.data.childLinks">
                <strong>{{value.name}}</strong>
                <span>{{value.url}}</span>
            </li>
        </ul>
    </div>
</button>

navigationgroup.html

navigationArea.cshtml

@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage<Umbraco.Cms.Core.Models.Blocks.BlockGridItem>

@{
    if (Model?.Areas.Any() != true) { return; }
}

@foreach(var area in Model.Areas)
{
    @await Html.GetBlockGridItemAreaHtmlAsync(area)
}

navigationArea.cshtml

navigationGroup.cshtml

@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage<Umbraco.Cms.Core.Models.Blocks.BlockGridItem<ContentModels.NavigationGroup>>

@if ((Model.Content.ChildLinks != null && Model.Content.ChildLinks.Any())
             && (!string.IsNullOrWhiteSpace(Model.Content.Title) || Model.Content.Link != null))
{
    <li class="nav-item mx-0 mx-lg-1 dropdown">
        @if(Model.Content.Link != null)
        {
            <a class="nav-link py-3 px-0 px-lg-3 rounded dropdown-toggle" target="@Model.Content.Link.Target" href="@Model.Content.Link.Url" id="@Model.Content.Key.ToString("N")" role="button" data-bs-toggle="dropdown" aria-expanded="false">
                @Model.Content.Link.Name
            </a>
        }
        else if(!string.IsNullOrWhiteSpace(Model.Content.Title))
        {
            <a class="nav-link py-3 px-0 px-lg-3 rounded dropdown-toggle" href="#" id="@Model.Content.Key.ToString("N")" role="button" data-bs-toggle="dropdown" aria-expanded="false">
                @Model.Content.Title
            </a>
        }
        <ul class="dropdown-menu" aria-labelledby="@Model.Content.Key.ToString("N")">
            @foreach(var childLink in Model.Content.ChildLinks)
            {
                <li><a class="dropdown-item" target="@childLink.Target" href="@childLink.Url">@childLink.Name</a></li>
            }
        </ul>
    </li>
}
else
{
    <li class="nav-item mx-0 mx-lg-1"><a class="nav-link py-3 px-0 px-lg-3 rounded" target="@Model.Content.Link.Target" href="@Model.Content.Link.Url">@Model.Content.Link.Name</a></li>
}

navigationGroup.cshtml

mainNavigation.cshtml

@inherits UmbracoViewPage

@{
    var siteSettings = Model.GetSiteSettings();
    if (siteSettings is null) return;
}

<nav class="navbar navbar-expand-lg bg-secondary text-uppercase fixed-top" id="mainNav">
    <div class="container">
        <a class="navbar-brand" href="#page-top">@siteSettings.SiteName</a>
        <button class="navbar-toggler text-uppercase font-weight-bold bg-primary text-white rounded" type="button" data-bs-toggle="collapse" data-bs-target="#navbarResponsive" aria-controls="navbarResponsive" aria-expanded="false" aria-label="Toggle navigation">
            @Umbraco.GetDictionaryValue("Menu", "Menu")
            <i class="fas fa-bars"></i>
        </button>
        <div class="collapse navbar-collapse" id="navbarResponsive">
            <ul class="navbar-nav ms-auto">
                @await Html.GetBlockGridHtmlAsync(siteSettings, "mainNavigation")
            </ul>
        </div>
    </div>
</nav>

mainNavigation.cshtml

area.cshtml

@using Umbraco.Extensions
@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage<Umbraco.Cms.Core.Models.Blocks.BlockGridArea>

@await Html.GetBlockGridItemsHtmlAsync(Model)

area.cshtml

areas.cshtml

@using Umbraco.Extensions
@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage<Umbraco.Cms.Core.Models.Blocks.BlockGridItem>
@{
    if (Model?.Areas.Any() != true) { return; }
}

@foreach (var area in Model.Areas)
{
    @await Html.GetBlockGridItemAreaHtmlAsync(area)
}

areas.cshtml

default.cshtml

@using Umbraco.Extensions
@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage<Umbraco.Cms.Core.Models.Blocks.BlockGridModel>
@{
    if (Model?.Any() != true) { return; }
}

@await Html.GetBlockGridItemsHtmlAsync(Model)

default.cshtml

items.cshtml

@using Umbraco.Cms.Core.Models.Blocks
@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage<IEnumerable<BlockGridItem>>
@{
    if (Model?.Any() != true) { return; }
}

@foreach (var item in Model)
{
    var partialViewName = "blockgrid/Components/" + item.Content.ContentType.Alias;
    try
    {
        @await Html.PartialAsync(partialViewName, item)
    }
    catch (InvalidOperationException)
    {
        <p>
            <strong>Could not render component of type: @(item.Content.ContentType.Alias)</strong>
            <br />
            This likely happened because the partial view <em>@partialViewName</em> could not be found.
        </p>
    }
}

items.cshtml