利用ASP.NET SiteMap生成与Bootstrap"兼容"菜单

Bootstrap是Twitter推出的一个开源的用于前端开发的工具包。它由Twitter的设计师Mark Otto和Jacob Thornton合作开发,是一个CSS/HTML框架。本文提供了一个解决方案利用ASP.NET SiteMap生成与Bootstrap“兼容”的菜单。具体的原理很简单,就是利用SiteMap读取预先定义的网站结构,按照Bootstrap的标准生成相应的HTML。[源代码从这里下载]

我们将基于菜单的呈现定义在HtmlHelper的扩展方法中。如下面的代码片断,扩展方法RenderBootstrapMenu具有一个缺省的参数siteMapProviderName ,表示读取SiteMap结构采用的SiteMapProvider的配置名称。在该方法中,我们通过指定的SiteMapProvider(如果没有指定,则采用默认配置的SiteMapProvider)得到代表整个SiteMap根节点的SiteMapNode对象,并将其子节点(以及子节点的子节点,…)转换成相应的HTML。

class BootstrapMenuExtensions

   2: {        
)
   4:     {
string.IsNullOrEmpty(siteMapProviderName) ?
   6:             SiteMap.Providers[siteMapProviderName] :
   7:             SiteMap.Provider ?? SiteMap.Providers.Cast<SiteMapProvider>().First();
new MvcHtmlString( RenderMenu(siteMapProvider.RootNode.ChildNodes));
   9:     }
  10:  
string RenderMenu(SiteMapNodeCollection siteMapNodes)
  12:     {
);
);
);
  16:  
in siteMapNodes)
  18:         {
  19:             ul.InnerHtml += GetMenuItemHtml(node);
  20:         }
return ul.ToString();
  22:     }
  23:  
string GetMenuItemHtml(SiteMapNode siteMapNode)
  25:     {
);
);
  28:  
);
, siteMapNode.Url);
, siteMapNode.Description);
  32:         link.SetInnerText(siteMapNode.Title);
  33:  
if (!siteMapNode.HasChildNodes)
  35:         {
  36:             li.InnerHtml += link.ToString();
return li.ToString();
  38:         }
  39:  
);
);
);
);
  44:         link.InnerHtml += caret.ToString();
  45:  
);
);
in siteMapNode.ChildNodes)
  49:         {
  50:             ul.InnerHtml += GetSubItemHtml(node);
  51:         }
  52:         li.InnerHtml += link.ToString();
  53:         li.InnerHtml += ul.ToString();
return li.ToString();
  55:     }
  56:  
string GetSubItemHtml(SiteMapNode siteMapNode)
  58:     {
);
  60:  
);
, siteMapNode.Url);
, siteMapNode.Description);
  64:         link.SetInnerText(siteMapNode.Title);
  65:         li.InnerHtml += link.ToString();
  66:  
if (siteMapNode.HasChildNodes)
  68:         {
);
);
  71:  
);
);
);
in siteMapNode.ChildNodes)
  76:             {
  77:                 ul.InnerHtml += GetSubItemHtml(node);
  78:             }
  79:             li.InnerHtml += ul.ToString();
  80:         }
return li.ToString();
  82:     }
  83: }