Iteration in shape templates

Topics: Customizing Orchard, General
Apr 18, 2011 at 11:57 AM

Hi guys,

I'm very new to Orchard, and @Razor in general and need to extend the existing menu with a unique set of CSS classes.

I have identified where to find the template for the menu, Menu.cshtml and MenuItem.cshtml but need to determine how many items are in the collection, and add a new class depended of whether it's the last or first item in the collection. I've searched online for similar posts but could not find anything concrete, I can add classes and attributes using Model.Attributes.Add("") and Model.Classes.Add("").

Is there any way that I can create an iterator within MenuItem.cshtml, where I need to add the class rules, I've tried the following:

    // odd formatting in this file is to cause more attractive results in the output.
    var items = (IEnumerable<dynamic>)Enumerable.Cast<dynamic>(Model);

    string[] colors = new string[] { "yellow", "blue", "pink", "orange", "lblue", "purple" };
    var count = 1;
if (!HasText(Model.Text)) {
} else {
    string requestUrl = Request.Path.Replace(Request.ApplicationPath, string.Empty).TrimEnd('/').ToUpperInvariant();
    string modelUrl = Model.Href.Replace(Request.ApplicationPath, string.Empty).TrimEnd('/').ToUpperInvariant();
    if ((!string.IsNullOrEmpty(modelUrl) && requestUrl.StartsWith(modelUrl)) || requestUrl == modelUrl) {        
    // add necessary element styles
    Model.Classes.Add(string.Format("parent item{0} {1}", count, colors[count - 1]));

    if (count == 1) {
        Model.Attributes.Add("id", "current");
    var tag = Tag(Model, "li");
    <a href="@Model.Href"><span>@Model.Text</span></a>
    if (items.Any()) {

In green, is what I'm trying to achieve.

Thanks for the assistance in advance.



Apr 18, 2011 at 12:57 PM

The DisplayChildren function (in WebViewPage.cs) just looks like this:

        public IHtmlString DisplayChildren(dynamic shape) {
            var writer = new HtmlStringWriter();
            foreach (var item in shape) {
            return writer;

So in your above example, you'd replace the @DisplayChildren(Model) line with this:

@foreach (var item in items) {
    if (count == 1) item.Classes.Add("first");

Apr 18, 2011 at 12:59 PM

Thank you randompete.