Sitecore : Top Navigation

This is my first Sitecore CMS post, so I thought I will start with something very simple, what could be more simpler than ‘Top Navigation’

Sitecore gives you the flexibility to render items by XSLT or by .NET UserControls.

I prefer using .NET Controls over XSLT for various reasons

1. XSLT are easy to implement and fast but difficult to maintain when you have to introduce complex logic for navigation (like if user is logged in or not)
2. XSLT are difficult to debug (imagine going through 3 to 4 foreach loops!)
3. XSLT are so old, I feel like working in 90s (but people still use it)

Anyways, I will implement a very simple top navigation with a repeater in a .NET UserControl which will take top childrens of ‘Home’ Item/Node and render them
as top navigation

Here is the code for repeater (pretty standard)

<asp:Repeater ID="RepeaterTopNavigation" runat="server" OnItemDataBound="RepeaterTopNavigation_ItemDataBound">
<HeaderTemplate>
<ul>
<li><a href="/home.aspx">Home</a></li>
</HeaderTemplate>

<ItemTemplate>
<li>
<asp:HyperLink ID="HyperLinkTopNavigation" runat="server"></asp:HyperLink>
</li>
</ItemTemplate>

<FooterTemplate>
</ul>
</FooterTemplate>
</asp:Repeater>

And here is the code behind for the repeater

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Sitecore.Data.Items;
using Sitecore.Links;

namespace SampleSite.Controls
{
public partial class TopNavigation : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
//get the home item, this is hardcoded but you can define it in web.config
Item home = Sitecore.Context.Database.GetItem("/sitecore/content/home");
//get all children from home using Sitecore API
Item[] children = home.Children.ToArray();
//Bind the children to repeater
RepeaterTopNavigation.DataSource = children;
RepeaterTopNavigation.DataBind();

}

public void RepeaterTopNavigation_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
//gets the current data item from RepeaterItemEventsArgs and cast it as a Sitecore Item
Item currentItem = (Item)e.Item.DataItem;

//check if it is not null, safety first
if (currentItem != null)
{

//check if it is coming from Item or Alternating Item template
if (e.Item.ItemType == ListItemType.Item || 
          e.Item.ItemType == ListItemType.AlternatingItem)
{

//Find the HyperLink control that has been defined in repeater
HyperLink topNavigation = (HyperLink)e.Item.FindControl("HyperLinkTopNavigation");
//Use Sitecore API to get the link to the Item and upadte the href property of link
topNavigation.NavigateUrl = LinkManager.GetItemUrl(currentItem);
//Assign name to the link
topNavigation.Text = currentItem.Name;

}
}
}
}
}

Explanation

1. Get the home Item
2. Get the children of home Item as array
3. Bind them to repeater
4. For OnItemDataBound, cast the DataItem as Sitecore Item and update the HyperLink property for each

Drop the control on your main layout and check for any build errors.

Thats it!