Articles in this series
Part 1: The requirements
Part 2: Installing Sitecore and setting up a Visual Studio solution
Part 3: Architecture
Part 4: The basic layouts
Part 5: Identity and documents
Part 6: Navigation
Part 7: The homepage - content oriented spots
Part 8: The homepage - presentation oriented spots
Part 9: News
Part 10: Search
Part 11: Deploying the solution
The navigation component
The navigation component is responsible for allowing the user or visitor to navigate on the site. In our simple information site, we are going to have several presentations, which enable this:
- Left navigation: This is the main menu on the site and works as many menus do. Initially it shows the top level in the hierarchy. When the user selects an item in the top level, it will show the next level for that given item; and so forth.
- Global navigation: This is static menu shown in the header of the site. This menu shows the same menu items throughout the site, and it is therefore pretty simple.
- Sitemap: This is a page showing all the menu items in a nice hierarchical structure.
Defining the templates
There are a couple of content fields needed for every template, which should be shown in a navigation presentation. First of all we want a navigation title field. This is needed as editors often want to name an item something different in the rather limited space available in a menu, then what can be used on the document itself. For instance imagine a document written on LearnSitecore called “Learn Sitecore welcomes a new contributor”. This title is way too long for a navigation component, so it would be nice if I could add the navigation title “New contributor”.
The second field we need to define is a “Show this page in the menu” checkbox. This will enable the editors to exclude pages from the menu structure. For instance imagine that you want to implement a form called “Request an article”. After the user has entered his request, he will be redirected to a page thanking him for the request and confirming that it has been sent. This confirmation page shouldn’t be shown in the navigation, so we should allow the editor to exclude it.
So we have two fields which belong and are needed by the navigation component. We don’t want to declare the fields on every single template, which should be shown in the menu. This would make the solution hard to maintain and extend and further it would create dependency between the different components. Therefore we are going to declare the fields in the navigation component. The presentations only use these fields, so there are no dependencies on other components. In that way we create sort of an interface which every item need to inherit/implement if it is to be shown in the navigation presentations. We call this an interface template – a template which defines what fields are necessary for a component or presentation to work.
So in this case we are going to create a template called navigable. The interface being that if an item inherits from this template, it will be possible to present the item in the navigation presentations. Create a template with the fields Navigation_Title and Navigation_ShowInMenu like this:
The pagetypes that needs it can now inherit from this.
The left navigation presentation
Now we are going to create the presentation for the left navigation. Again we are going to use XSLT, as this is just a simple information site. So go ahead and create an XSLT rendering called LeftNavigation like this:
Add the XSLT presentation to a newly created Visual Studio solution for the navigation component (like shown in the previous articles) and we are now ready to develop.
Often it is easier to develop if you can follow the progress by seeing the presentation, while you are developing it. So start by adding the presentation to the pagetypes you need. In this example we are going to add the presentation to the NormalPage pagetype:
Now that we have added the presentation do a publish and enter a test text in the XSLT and see that it comes out in the right place. You should see something like this:
The first thing we need to do in our presentation is to determine the root of the navigation. This is needed as the menu will always have a given root and all children should be shown in a hierarchical matter. As the left menu should start with everything from the home node and down, we need to locate the home node. The easy solution would of cause be to hard code the path to the home node. However this would make the site rather static, as you would not be able to rename any of the items in the path to the node. Further the left navigation wouldn’t support multiple sites in Sitecore as the menu would be the same on different sites. For more info on multiple sites in Sitecore see this article.
Now another possibility would be to look for the current nodes ancestors and find the first node, which is based on the home node template. However this isn’t very flexible either. First of all we would create a dependency on the pagetype component, which we don’t want (it would be a circular reference). Secondly it would only be possible to reset the navigation root, by creating a new home node.
So we need a way to determine what should be the root of the navigation component. Thanks to multiple inheritance in templates, we can use a template for this. What we need to do is create a template which indicates that an item is a root of the navigation – lets call this template _menuRoot. It needs no fields, as it just indicates a property of an item and doesn’t contain any data:

Now that we have this indicator of the root, we can let all pagetypes, which should reset the menu inherit from this template.
Currently we don’t have a root which should reset the menu, as we don’t have a frontpage template. So we need to create that in the pagetypes component (remember a friendly icon, as shown in the article about helping the editors) and make it inherit from the _menuRoot template:
To be able to test the left navigation go and create some example content in the content tree:
Good… We are now ready to start developing. :)
As mentioned the first thing we need to do is find the item, which should be the root of the left navigation. This means we should iterate over the ancestors of the current item and find the first one, which inherits from the _menuRoot template. We can use XPath for this, which should look something like this:
< xsl:variable name = "home" select="ancestor-or-self::item[sc:IsItemOfType('_menuRoot',.)]"></xsl:variable>
The sc:IsItemOfType is an XSL helper method provided by the Sitecore API. This method tests whether an item inherits from a template, which is named the string you provide in the first parameter. In this case _menuRoot.
Now that we have found the root, we can start the real task of rendering the menu. We can divide the needed functionality into separate XSLT methods with different responsibility. What we need is the following:
- A method that iterates over the items, that needs to be rendered.
- A method that renders an item in the left navigation.
We start with the method that iterates over all the nodes we render, we call this method TraverseChildren, as it will traverse over all the children of a specified item.
We need a parameter to this method/xsl template, as we need to know which items children we need to iterate over. The template with a parameter can created like this:
<xsl:template name="TraverseChildren">
<xsl:param name="item"></xsl:param>
</xsl:template>
Now we need to find all the children, which should be rendered in the left navigation. This is pretty straight forward:
<xsl:variable name="RenderableChildren" select="$item/item[sc:fld('Navigation_ShowInMenu',.) = '1']"/>
Here we use the parameter called “item” and iterate over all the children where the field Navigation_ShowInMenu equals one, which means the checkbox is checked.
The HTML that renders the menu should be using the list tag (ul, li). As XHTML doesn’t allow empty UL tags, we need only to render something out, if the number of children is greater than zero. This can be done like this:
<xsl:if test="count($RenderableChildren) > 0">
</xsl:if>
Now that this is determined we can start creating the list of navigation items. This is done by using the XSL for-each element like this:
<ul>
<xsl:for-each select="$RenderableChildren">
...
</xsl:for-each>
</ul>
Now we can call our second XSLT method/template, which we haven’t created to render the item.
<xsl:call-template name="RenderItem">
<xsl:with-param name="Item" select="."></xsl:with-param>
</xsl:call-template>
Now comes the tricky part. The left navigation can contain multiple levels, but the next level should only be rendered if one of the items children or it self is selected. For instance if you take a look at the example content tree we created earlier, the item named testpage12 should only be rendered if TestPage1 or one of its children is selected. If this is the case, we need to call the TraverseChildren method recursively.
The easy way to determine if we need to call the method recursively is to iterate over all the children of current node and see if it is selected. However this doesn’t perform very well as there may be 1000s of children. So we need to turn the picture around and take the currently selected node by the user and see if the node we are currently iterating over is an ancestor of that item. In that way we only look upwards in the tree, which limits the number of nodes we iterate over to the amount of levels in the content hierarchy.
Note: As a rule of thumb you should never iterate over all descendants of a given item
Sitecore parses the current user selected item in the parameter sc_currentitem. This gives us the following line to determine if we should call the method recursively:
<xsl:if test="current()/@id = $sc_currentitem/ancestor-or-self::item/@id">
Please note that we compare the attribute id and not the item itself. This is absolutely necessary to make the rendering perform. If you don’t do so, XSL will convert the item and all of its children to XML trees and compare them. If the item has thousands of children this tree can be rather large and give some extreme spikes in your memory usage.
Now if this test returns true you should call the method recursively. Adding this to the method and a level parameter to the template for styling purposes your XSLT should look something like this:
<xsl:template name="TraverseChildren">
<xsl:param name="level"></xsl:param>
<xsl:param name="item"></xsl:param>
<xsl:variable name="RenderableChildren" select="$item/item[sc:fld('Navigation_ShowInMenu',.) = '1']"/>
<xsl:if test="count($RenderableChildren) > 0">
<xsl:variable name="LevelCssClass" select="concat('MenuLevel',$level)"></xsl:variable>
<ul class="{$LevelCssClass}">
<xsl:for-each select="$RenderableChildren">
<xsl:variable name="selected">
<xsl:if test="current()/@id = $sc_currentitem/@id">
Selected
</xsl:if>
</xsl:variable>
<xsl:call-template name="RenderItem">
<xsl:with-param name="Item" select="."></xsl:with-param>
<xsl:with-param name="Selected" select="$selected"></xsl:with-param>
</xsl:call-template>
<xsl:if test="current()/@id = $sc_currentitem/ancestor-or-self::item/@id">
<xsl:call-template name="TraverseChildren">
<xsl:with-param name="level" select="$level+1"/>
<xsl:with-param name="item" select="."/>
</xsl:call-template>
</xsl:if>
</xsl:for-each>
</ul>
</xsl:if>
</xsl:template>
Now all we need to do is implement the RenderItem method/template. This is fairly easy to do.
<xsl:template name="RenderItem">
<xsl:param name="Item"/>
<xsl:param name="Selected"></xsl:param>
<li class="{$Selected}">
<sc:link select="$Item">
<sc:text select="$Item" field="Navigation_Title"/>
</sc:link>
</li>
</xsl:template>
Notice here how I use the sc:link and sc:text XslControls which Sitecore provides through the API. These automatically create a link and pulls out the text from the Navigation_Title field.
The last thing we need to do is call the TraverseChildren with the root node of the menu. This can be done in the Main template of the XSLT:
<xsl:template match="*" mode="main">
<div class="LeftNavigation">
<xsl:variable name="home" select="ancestor-or-self::item[sc:IsItemOfType('_menuRoot',.)]"></xsl:variable>
<xsl:call-template name="TraverseChildren">
<xsl:with-param name="level" select="0"/>
<xsl:with-param name="item" select="$home"/>
</xsl:call-template>
</div>
</xsl:template>
If you add a little styling to the control (in the design component) you should now see something like this:

That is it. You have now created the most complex presentation – the left menu.
The global navigation properties
The next part we need to develop is the global navigation. This is a fairly simple data presentation, so we are going to use an XSLT again. The first thing we need to do is to create a content structure for the global navigation elements. We need to create a folder for the root as the same way we created a root for the left navigation. That means we need to create a root template and a content item in the pagetypes component:

Now we have a folder for the global navigation. To allow editors to create pages under this folder we need to setup insert options. This should be done on the standard values on the folder. So create the standard values and allow the editor to insert items of templates NormalPage and create an example content structure in the content tree:

Now that we have that in place, we can get started on the presentation. So create the rendering as we have done before.

As we did when developing the left navigation the first thing we need to do is to find the root of the menu, no matter what the current item is in Sitecore. Again this should be dynamic so we don’t hardcode paths’ and disallow multiple sites. In the same way as with the leftNavigation we are going to look upwards in the tree to find the root of the site. We are going to define that the global navigation folder should always be found as a direct child of the root of the left menu. We could work with other concepts, but this is a natural and simple way, which fits our needs just fine. So the root is found like this:
<xsl:variable name="root" select="ancestor-or-self::item[sc:IsItemOfType('_menuRoot',.)]/item[sc:IsItemOfType('_globalMenuRoot',.)]"/>
Now all we need to do is iterate over all the items and render a link to them. This is done like this:
<xsl:variable name="children" select="$root/item[sc:fld('Navigation_ShowInMenu',.)='1']"/>
<xsl:if test="count($children) > 0">
<ul>
<xsl:for-each select="$children">
<li>
<sc:link select=".">
<sc:text field="Navigation_Title"/>
</sc:link>
</li>
</xsl:for-each>
</ul>
</xsl:if>
Now we just need to apply the rendering to the correct page types:

That’s it. Easy-peasy-lemon-squezzy!
The sitemap
The only thing we now miss in the navigation component is the sitemap. I am not going to go through all the steps and explain it in detail, as the sitemap is very similar to the left navigation – except that the complete tree is going to be listed. You can download the source code if you want to take a closer look.
After you have created the presentation you need to create a pagetype for the sitemap. You need to define what “interface templates” it should hold. In my case I want it to inherit from navigable as it should be presentable in the global navigation. Further I want to inherit from documentHeader as I want to present a title and abstract field in the top of the page. So I create a template like this:

Now you just need to set the presentations on the __Standard values. One thing you should know about a sitemap is, that it potentially iterates over a huge amount of items, if the content tree is very big. So in this case it would be a good idea to add HTML caching to the presentation. If you want to know more about Sitecores caching read this article.
You can apply caching to the presentation like this:

Here you set that the outputted HTML should be cached. You can set when the cache should be varied. This means that Sitecore can cache different versions of the outputted HTML. For instance you might want to have different caches for different query strings if your presentation varies based on them (like paging). You can read more about setting up caching in the SDN Presentation Component Reference.
Now that you have set that up, you have finished the navigation component. Congratulations!
You can download the
source and a Sitecore package here.