When everything’s an Item, you have to choose your own information architecture. Today we’ll look at information architecture for supporting the most common forms of on-page navigation found on websites since, well, the creation of websites.
On the Menu
We’ll limit our conversation to navigation menu systems that help structure a site for the visitor. Specifically:
- Section Navigation
- “Static” Navigation
Of these three common navigation components, within Sitecore the first two are usually “dynamically generated”. Authors build out their site, and the navigation automatically builds with it. Static navigation, on the other hand, covers times when Authors want to “hide” Items from navigation, or when a site’s design limits the ability for menus to grow automatically.
Here’s a Sitecore 101 question: What’s the most efficient way to get the list of Items between the Context Item (current page) and the home page of the site?
If your answer didn’t involve
contextItem.Axes.GetAncestors(), I’d be shocked.
This particular API trick gives you all of the ancestor Items (from /sitecore down to your current page) in the correct order to pass them to a for-loop in your View. However, using it directly makes some assumptions. Are all of the members of this collection pages? Are there any intervening folders? Does your Content Tree’s shape accurately reflect the path that you want to advertise to the visitor?
In my experience, the answer to the last question: Does the “breadcrumb” path match the URL structure of your site? should always be yes!, or as close as it can be. There are a few good reasons:
From an SEO perspective, you’re setting up keyword silos: traveling from more general relevance to more specific relevance the deeper you go into the content tree. Search engines like this because it allows them to better classify your content, and should result in higher search results rankings for the keywords you’re targeting.
From a Sitecore architecture perspective, having a deep, rather than wide, content tree gives you more opportunities to craft “automatic” Item security via inheritance, as well as use ancestry to control things like meta-information. This will be a recurring theme as section navigation also requires careful tree design.
Mind the Gap
What do you do if your ancestor path contains folders? For example, when you need to store a lot of “sibling” content organized by some sort of classification layer to aid in locating Items as well as to prevent the Content Editor from bogging down.
One of the more common solutions is to ignore intervening folders in breadcrumbs. Concentrate on semantically significant ancestors such as landing pages that explain to the user where the page is on the site without mirroring the URL 100%.
Another common solution is to suppress breadcrumbs altogether on content that is organized into collections. These deep collections tend to have navigation for searching, filtering, and sorting their members independent of the gross site navigation. Breadcrumbs are used when there aren’t tailor-made navigation features.
Forming a sort of “Table of Contents” for a particular site area, section navigation is another Sitecore 101 problem: Draw navigation that starts at the most significant ancestor and shows all relevant options on the tree from that point down to the Context Item, including children of the Context Item. Often referred to as Accordion navigation, and made ubiquitous in the days of C-shaped web pages, section navigation is now often integrated into landing page bodies or mega-menus, but the assembly remains the same.
Dynamically generated Section Navigation requires two “anchor” semantics in order to function properly:
- Items that indicate the “top” of a section in the content tree
- Items that indicate they are “members” of the section navigation
The first semantic concept allows your navigation builder to start at the context item and crawl ancestors until told to “stop” by the appearance of a root Item.
The second concept allows your crawler to know what should be included in the rendered menu system.
Like breadcrumbs, we probably want to ignore or traverse intervening Folders, but unlike breadcrumbs, which are a straight shot up the content tree, Section navigation has to reveal the entire branch, well, only branch nodes that have presentation. This has become increasingly important in an Experience-Editor driven world, where pages typically keep the datasources to their renderings as children or descendants, somewhat co-mingled with actual child pages.
As mentioned in the intro, static navigation is a different beast. I generally use the term to refer to “heavily designed” menu systems such as:
- The ubiquitous menu bar at the top of virtually every website ever developed.
- Footer links, whether it’s just a few disclaimers or a “fat footer” that resembles a site map.
- little groups of “permanent” links that are generally squeezed into one of the areas above, but sometimes do interesting things like ride along the side of content as you scroll.
I use the term “static” because traditionally these options appear everywhere on a site and could be “hard wired” in HTML, with no concession for author management. Within Sitecore, these menu systems are generally “locked down” and are usually not modifiable through Experience Editor.
These menus generally have presentation that is “fragile”. It wasn’t meant (graphically designed) to handle an infinite count of links, links whose inner text exceeds a certain character count, an infinite number of “levels”, etc. Menus like this generally have other interesting business requirements:
- Links need to be listed in an (apparently arbitrary) order that is not alphabetical, date based, or as ordered in the Content Tree.
- The text on each link may need to be “tweaked” for brevity, or to provide accommodations for synonyms or abbreviations.
- Links to external websites may need to be co-mingled with links to pages maintained within Sitecore.
- Links need to be grouped and ordered in ways that are not visible by looking at the content tree.
Don’t forget, content authors will still want explicit abilities to customize these navigation menus: add/remove items, adjust their names, sometimes their styles, etc.
The best way to handle the above static navigation requirements is by creating a mini-branch in the Sitecore Content tree. The branch is associated with the site, but grows apart from it. Branch members don’t have deep content, instead their job is to point at the actual content (page) that they represent. Items in the branch typically have a link field, and may have additional fields to help control aspects of presentation relative to their individual menu’s appearance. Renderings then reference these Navigation branches to produce the menu systems on-page.
This blog post features some Sitecore basics, or at the very least “well understood problems.” I’ve seen some fairly disastrous implementations of everything from breadcrumbs to should-have-been-static navigation. I’ve also seen seasoned teams start working on these problems from scratch time & time again. If you’d like a time-tested approach to these problems that allows you to save some time and put value on the customer’s table sooner, Constellation has your back.
Constellation.Feature.Navigation contains the semantic Template flags you need to build breadcrumbs, section navigation and static (or “declared”) navigation. It also contains efficient data repositories for getting that information out of Sitecore and ready for your Renderings. As usual, Constellation leaves the HTML output entirely up to your team. Read up on it here. If you’re feeling brave, you can also install the NuGet package, and if you’d like a deep dive, the code is available on GitHub.