Creating a Breadcrumb Rendering

Here we will walk through the steps to create a basic breadcrumb rendering that can be included in all pages on a site. Here’s an example of the output as it would appear using Bootstrap 4.x:

Note the context item “Our Executive Team” is not linked.

The markup looks like this:

<nav aria-label=breadcrumb>
<ol class=breadcrumb>
<li class=breadcrumb-item>
<a href="/">Home</a>
</li>
<li class=breadcrumb-item>
<a href=/about-us>About Us</a>
</li>
<li class="breadcrumb-item active" aria-current=page>
Our Executive Team
</li>
</ol>
</nav>

Within Sitecore, the content tree for this particular breadcrumb is:

The context item “our-executive-team” is highlighted.

Prerequisites

Make sure you’ve installed the NuGet package, built and deployed your Sitecore project.

Make sure Items in your content tree inherit from “Page” and “Navigation Title” as described here.

For instant gratification, make sure you’ve Published after the above changes.

The Controller

I prefer Controller Renderings because it makes it possible to encapsulate rendering logic discrete from the actual markup produced. Following this philosophy, here’s a basic Controller:


using System.Web.Mvc;
using Constellation.Feature.Navigation.Models;
using Constellation.Feature.Navigation.Repositories;
using Sitecore.Data.Items;
using Sitecore.Mvc.Presentation;
namespace Website.Areas.ExampleSite.Controllers.Navigation
{
    public class ExampleBreadcrumbController : Controller
    {    
        public ExampleBreadcrumbController(IBreadcrumbNavigationRepository repository)
        {        
            this.Repository = repository;
        }

        public IBreadcrumbNavigationRepository Repository { get; set; }

        public ActionResult Index()     
        {         
             Breadcrumb[] model = GetModel(RenderingContext.Current.PageContext.Item);
             string view = GetViewName();
             return View(view, model);
        }

        protected Breadcrumb[] GetModel(Item contextItem)
        {
            /* This is the *only* time you should use Sitecore.Context, as there's no way to
             * get the Site from the RenderingContext.
             */

             return Repository.GetNavigation(contextItem, 
Sitecore.Context.Site.SiteInfo);
         }

         protected string GetViewName()
         {
             return "~/Areas/ExampleSite/Views/Navigation/ExampleBreadcrumb.cshtml";
         }
    }
}

Above you can see that we’re using Dependency Injection to get an instance of IBreadcrumbRepository. To get an array of Breadcrumb objects to render, we need to supply the Repository with a reference to the Context Item (retrieved from RenderingContext) and the Context Site, which will tell the Breadcrumbs what Item in the Context Item’s ancestor path represents the home page of the site.

The Model

IBreadcrumbRepository returns an array of Breadcrumb objects. These objects are essentially read-only ViewModels and contain only one method GetBestLinkText() that is essentially syntax candy.

Breadcrumb Properties:

  • ID of the Item it represents
  • DisplayName of the Item it represents
  • Url retrieved through your currently active (context) LinkManager
  • NavigationTitle from the Navigation Title field in base templates
  • IsContextItem true if the ID matches that of the Context Item

Breadcrumb objects in the array are supplied ancestor-first, Context item last.

The View

@model Constellation.Feature.Navigation.Models.Breadcrumb[] 
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
@foreach (var breadcrumb in Model)
{
if (breadcrumb.IsContextItem)
{
<li class="breadcrumb-item active" aria-current="page">
@breadcrumb.GetBestLinkText()
</li>
continue;
}
<li class="breadcrumb-item">
<a href="@breadcrumb.Url">@breadcrumb.GetBestLinkText()</a>
</li>
}
</ol>
</nav>

We can see above that the View code is nice and boring. Aside from the Bootstrap 4.x style nav and ol tag requirements, we’re basically rendering a series of list item tags, in the order they are provided to us. The objects provided in the Model allow us to quickly discern which member of the list is the Context Item for special treatment. this code could easily be modified to suit any markup requirements.