After keeping an eye on the Orchard forums and then doing some work on a clients website that has been implemented in Orchard, I soon became one of those people needing a decent menu. So, I thought to myself, well what does orchard have that I can use, after all – I don’t really want to have to do a lot of work just for a menu.
Note : This is all based around the last iteration of Orchard within Visual Studio 2008 framework 3.5.
So what does Orchard have that I can use…
1. Admin page for Menu
2. Allows you to store menu positions as 1 1.1 1.1.1 2 2.2 etc…
3. You can override the menu within your theme
Okay, so I got to thinking, if I can store the positions broken down like this, why cant i retrieve them like this, and go on to build the necessary menu steps? Well I can… here is how..
Step 1: In your theme, create a Menu.ascx file.
And drop this code in to it. (this is a modified version of the one located in Orchard.Themes)
<%@ Control Language="C#" Inherits="Orchard.Mvc.ViewUserControl<Orchard.Mvc.ViewModels.BaseViewModel>" %>
<%@ Import Namespace="Orchard.Utility.Extensions"%><%
var menu = Model.Menu.FirstOrDefault();
if (menu != null && menu.Items.Count() > 0) { %>
<ul class="menu" role="navigation"><%
int counter = 0, count = menu.Items.Count() - 1;
int previousLevel = 1;
int currentLevel = 1;
foreach (var menuItem in menu.Items.OrderBy(m => m.Position)) {
var sbClass = new StringBuilder(10);
if (counter == 0)
sbClass.Append("first ");
if (counter == count) {
sbClass.Append("last ");
}
if (string.Equals(menuItem.Href, Request.ToUrlString(), StringComparison.InvariantCultureIgnoreCase))
sbClass.Append("current ");
currentLevel = menuItem.Position.Split('.').Length;
if ((previousLevel == currentLevel) && counter >= 1){ %>
</li>
<%}
if (previousLevel < currentLevel) {
sbClass.Append("first ");%>
<ul>
<% }
if (previousLevel > currentLevel) {
for (int i = 0; i < (previousLevel - currentLevel); i++) { %>
</li> </ul>
<% } %> </li> <%}
var classValue = sbClass.ToString().TrimEnd();
var linkAttributes = new Dictionary<string, object>();
if (!string.IsNullOrEmpty(menuItem.AccessKey))
linkAttributes.Add("accesskey", menuItem.AccessKey);
%>
<li<%=!string.IsNullOrEmpty(classValue) ? string.Format(" class=\"{0}\"", classValue) : "" %>><%=Html.Link(menuItem.Text, menuItem.Href, linkAttributes)%>
<% previousLevel = currentLevel;
if (counter == count) { %>
</li>
<% for (int i = 1; i < previousLevel; i++) { %>
</ul> </li>
<% } }
++counter;
} %>
</ul>
<% } %>
Next head to your manage menu section in the admin screens…. usually http://localhost:30320/Admin/Navigation
Set up your positions like below… Click Update All

Next head back to your front page, and you should start seeing html like so….
<div class="menucontainer">
<ul class="menu" id="nav-one">
<li class="first"><a href="/">Home</a></li>
<li><a href="/Test/Gallery">Portfolio</a>
<ul class="nested">
<li class="last"><a href="/Test/Gallery/Item/University Work">University Work</a></li>
</ul>
</li>
</ul>
</div>
I admit, I have done this in a little bit of a rush, so there could be one or two bugs creeping around.
Okay once this is done… So can then apply Suckerfish or what ever over the top… i used http://be.twixt.us/jquery/suckerFish.php which is the jquery equivalent.
Happy Orchard Picking everyone.
Note : Fixed issue with it not showing the ‘First’ class correctly. 29/July/2010
Note : Fixed issue with missing closing </li>. 04/Aug/2010
Nick
Orchard Orchard, Orchard CMS