Html.SiteMap doesn't create a properly nested list

Feb 4, 2010 at 7:54 PM

Hi,

I've noticed that the Html.SiteMap helper method doesn't create a properly nested list, it seems to wrap each sub item in it's own UL. This can be fixed with the following code:

        public static string SiteMap(this HtmlHelper helper, System.Web.SiteMapNode rootNode, string cssClass)
        {
            // String builder
            var sb = new StringBuilder();

            ParseChildNodes(sb, new SiteMapNodeCollection(rootNode), cssClass);

            return sb.ToString();
        }

        private static void ParseChildNodes(StringBuilder sb, System.Web.SiteMapNodeCollection childNodes, string cssClass)
        {
            bool shouldRender = false;
            foreach (SiteMapNode node in childNodes)
            {
                if (node.IsAccessibleToUser(HttpContext.Current))
                {
                    shouldRender = true;
                    break;
                }
            }

            if (shouldRender)
            {
                sb.Append("<ul");
                if (!string.IsNullOrEmpty(cssClass))
                {
                    sb.Append(string.Format(" class=\"{0}\"", cssClass));
                }
                sb.AppendLine(">");

                foreach (SiteMapNode node in childNodes)
                {
                    MvcSiteMapNode mvcNode = node as MvcSiteMapNode;
                    if (node.IsAccessibleToUser(HttpContext.Current) &&
                        (mvcNode == null || (mvcNode != null && !mvcNode.IsDynamic)))
                    {
                        sb.Append("<li>");

                        StringBuilder extraAttributes = new StringBuilder();
                        if (mvcNode != null)
                        {
                            if (!string.IsNullOrEmpty(mvcNode.Target))
                            {
                                extraAttributes.Append(" target=\"" + mvcNode.Target + "\"");
                            }
                            if (!string.IsNullOrEmpty(mvcNode.Title))
                            {
                                extraAttributes.Append(" title=\"" + mvcNode.Title + "\"");
                            }
                        }

                        sb.Append(string.Format("<a href=\"{0}\"{1}>{2}</a>", node.Url, extraAttributes, node.Title));

                        if (node.HasChildNodes)
                        {
                            ParseChildNodes(sb, node.ChildNodes, cssClass);
                        }

                        sb.Append("</li>");
                    }
                }

                sb.AppendLine("</ul>");
            }
        }