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…
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(<span class="str">'.'</span>).Length;
<span class="kwrd">if</span> ((previousLevel == currentLevel) && counter >= 1){ %>
</li>
<%}
<span class="kwrd">if</span> (previousLevel < currentLevel) {
sbClass.Append(<span class="str">"first "</span>);%>
<ul>
<% }
<span class="kwrd">if</span> (previousLevel > currentLevel) {
<span class="kwrd">for</span> (<span class="kwrd">int</span> i = 0; i < (previousLevel - currentLevel); i++) { %>
</li> </ul>
<% } %> </li> <%}
var classValue = sbClass.ToString().TrimEnd();
var linkAttributes = <span class="kwrd">new</span> Dictionary<<span class="kwrd">string</span>, <span class="kwrd">object</span>>();
<span class="kwrd">if</span> (!<span class="kwrd">string</span>.IsNullOrEmpty(menuItem.AccessKey))
linkAttributes.Add(<span class="str">"accesskey"</span>, menuItem.AccessKey);
%>
<li<%=!<span class="kwrd">string</span>.IsNullOrEmpty(classValue) ? <span class="kwrd">string</span>.Format(<span class="str">" class=\"{0}\""</span>, classValue) : <span class="str">""</span> %>><%=Html.Link(menuItem.Text, menuItem.Href, linkAttributes)%>
<% previousLevel = currentLevel;
<span class="kwrd">if</span> (counter == count) { %>
</li>
<% <span class="kwrd">for</span> (<span class="kwrd">int</span> 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
image_thumb1
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 . 04/Aug/2010
Nick