Как включить вывод asp: SiteMapPath в список?
Я очень незнакома с .NET и VB.NET и не могу понять, как это сделать. Скажем, у меня такой код:
<div class="breadcrumb">
<asp:SiteMapPath ID="SiteMapPath1" runat="server"></asp:SiteMapPath>
</div>
Он выводит связку <span>
с >
в качестве разделителей, примерно так:
<div class="breadcrumb">
<span id="ctl00_SiteMapPath1">
<a href="#ctl00_SiteMapPath1_SkipLink">
<img alt="Skip Navigation Links" height="0" width="0" src="/Bonfield/WebResource.axd?d=PEpmmIw6qvhaEC3hEwXGjgvJKlzc3DOMu_e-zW-n6pfl6YR-iYjwmlvrYPb689EslKxysA7aoh_x_ALjLs5QXiz7NG41&t=634245478914809245" style="border-width:0px;" />
</a>
<span>
<a href="/Bonfield/Default.aspx">Home</a>
</span>
<span> » </span>
<span>Showcase</span><a id="ctl00_SiteMapPath1_SkipLink"></a></span>
</div>
Как я могу превратить это в список, например:
<ul>
<li>Home</li>
<li>Showcase</li>
</ul>
Ответы
Ответ 1
Возможно, вы решили это сделать, но вы можете использовать эту функцию для прокрутки всех элементов в корневом каталоге Sitemap и их потомков и создания вложенного списка.
Вы можете удалить If item.HasChildNodes Then sb.Append(ListChildNodes(item))
, если вас интересует только верхний уровень
Public Function SiteMap() As String
Return ListChildNodes(System.Web.SiteMap.RootNode)
End Function
Private Function ListChildNodes(ByVal node As System.Web.SiteMapNode) As String
Dim sb As New System.Text.StringBuilder
sb.Append("<ul>")
For Each item As SiteMapNode In node.ChildNodes
sb.Append(String.Concat("<li><a href=""", item.Url, """>", item.Title, "</a></li>"))
If item.HasChildNodes Then sb.Append(ListChildNodes(item))
Next
sb.Append("</ul>")
Return sb.ToString
End Function
Для тех, кому нужна версия С#:
public string SiteMap()
{
return ListChildNodes(System.Web.SiteMap.RootNode);
}
private string ListChildNodes(System.Web.SiteMapNode node)
{
System.Text.StringBuilder sb = new System.Text.StringBuilder();
sb.Append("<ul>");
foreach (SiteMapNode item in node.ChildNodes)
{
sb.Append(string.Concat("<li><a href=\"", item.Url, "\">", item.Title, "</a></li>"));
if (item.HasChildNodes)
sb.Append(ListChildNodes(item));
}
sb.Append("</ul>");
return sb.ToString();
}
Затем в вашем коде вы можете просто вызвать вывод строки на страницу.
<h1>Site Map</h1>
<%=SiteMap()%>
</div>
Ответ 2
Пока вы не можете избавиться от тегов span, вы можете выполнить то, что хотите. Я столкнулся с этой же проблемой, потому что я использовал приобретенный шаблон сайта CSS/HTML, который хотел клиент, но все было основано на <ul>
и <li>
. Рефакторинг CSS был бы слишком болезненным, поэтому я нашел, что это решение хорошо работает без каких-либо изменений в коде CSS.
Вы сделаете две вещи:
- Переопределить шаблон по умолчанию Node с тем, который использует теги
<li>
- Оберните все это тегом
<ul>
Вот пример:
<ul style="list-style-type: none;">
<asp:SiteMapPath ID="SiteMapPath1" runat="server" >
<NodeTemplate>
<li>
<a href='<%# Eval("url") %>' title='<%# Eval("description") %>'><%# Eval("title") %></a>
</li>
</NodeTemplate>
</asp:SiteMapPath>
</ul>
Ответ 3
Ближайшим, о котором я могу думать, является размещение вашей карты сайта в элементе управления <asp:menu>
. Однако это будет выводиться как таблица html, но визуально отобразит список:
<asp:Menu ID="leftNavigation" runat="server" DataSourceID="SiteMapDataSource1"
StaticDisplayLevels="1" MaximumDynamicDisplayLevels="1">
</asp:Menu>
<asp:SiteMapDataSource ID="SiteMapDataSource1" runat="server" ShowStartingNode="false" />
Играйте со всеми параметрами стиля и форматирования, чтобы получить желаемый результат. См. здесь для подробного пошагового руководства.
О, и, конечно же, вы могли бы также рассмотреть использование дерева с помощью карты сайта (см. ту же страницу).
Ответ 4
Хотя это немного связано, это решение, которое фактически удаляет промежутки и отображает чистый список.
Во-первых, избавитесь от этих избыточных интервалов, изменив SiteMapPath
. Я получил класс NakedSiteMapPath
, который делает это. Он по-прежнему позволяет использовать явные промежутки в шаблонах, если необходимо:
/// <summary>
/// A SiteMapPath, that does not render span elements.
/// </summary>
/// <remarks>
/// To still allow explizit spans inside the node templates, immediately prefix the opening and closing span elements
/// with the literal
/// prefix "<!--KEEP NEXT SPAN-->" (without the double quotes)
/// Example:
/// <code>
/// <PathSeparatorTemplate><!--KEEP NEXT SPAN--><span class="icon icon--greater"><!--KEEP NEXT SPAN--></span>
/// </PathSeparatorTemplate>
/// </code>
/// Those spans (opening and closing) will be kept, but the prefix removed in the rendered output.
/// </remarks>
/// <devdoc>
/// The MSDN doc has a nice example about a customized breadcrumb with a dropdown menu here:
/// https://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.sitemappath%28v=vs.110%29.aspx
/// </devdoc>
[AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Minimal)]
[ToolboxData("<{0}:NakedSiteMapPath runat=server></{0}:NakedSiteMapPath>")]
public class NakedSiteMapPath : SiteMapPath {
/// <summary>
/// Outputs server control content to a provided <see cref="T:System.Web.UI.HtmlTextWriter" /> object and stores
/// tracing information about the control if tracing is enabled.
/// </summary>
/// <param name="writer">The <see cref="T:System.Web.UI.HtmlTextWriter" /> object that receives the control content.</param>
public override void RenderControl(HtmlTextWriter writer) {
//Render to a local string, then remove all unnecessary spans
StringBuilder myStringBuilder = new StringBuilder();
TextWriter myTextWriter = new StringWriter(myStringBuilder);
HtmlTextWriter myWriter = new HtmlTextWriter(myTextWriter);
base.RenderControl(myWriter);
string html = myStringBuilder.ToString();
//Remove all spans, except those opening and closing spans wich have been marked with the literal comment "<!--KEEP NEXT SPAN-->"
const string matchOpenExceptSkipPrefix = @"(?<!\<\!--KEEP NEXT SPAN--\>)<span>";
const string matchCloseExceptSkipPrefix = @"(?<!\<\!--KEEP NEXT SPAN--\>)</span>";
html = Regex.Replace(html, matchOpenExceptSkipPrefix, String.Empty);
html = Regex.Replace(html, matchCloseExceptSkipPrefix, String.Empty);
html = html.Replace(@"<!--KEEP NEXT SPAN-->", String.Empty);
//finally, write the naked html out.
writer.Write(html);
}
}
С этим пробелы исчезли. Чтобы иметь настраиваемые ссылки, например элементы li
, вам нужно будет использовать шаблоны, как уже предлагали другие. Здесь пример части страницы ASPX с NakedSiteMapPath
:
<ol class="breadcrumb" role="navigation" aria-labelledby="pagebreadcrumbs">
<my:NakedSiteMapPath runat="server"
PathDirection="RootToCurrent"
RenderCurrentNodeAsLink="False">
<PathSeparatorTemplate><!--KEEP NEXT SPAN--><span class="icon icon--greater"><!--KEEP NEXT SPAN--></span></PathSeparatorTemplate>
<CurrentNodeTemplate>
<li class="active" aria-selected="true">
<asp:Literal
Text='<%# Eval("Title") %>'
runat="server" />
</li>
</CurrentNodeTemplate>
<NodeTemplate>
<li>
<asp:HyperLink
ID="lnkPage"
Text='<%# Eval("Title") %>'
NavigateUrl='<%# Eval("Url") %>'
ToolTip='<%# Eval("Description") %>'
runat="server" />
</li>
</NodeTemplate>
</my:NakedSiteMapPath>
</ol>
Ответ 5
Лучшим вариантом для этого является преобразование SiteMapPath для использования шаблонов.
В <NodeTemplate>
вы можете разместить элементы <li>
в нужном вам формате.
В <PathSeparatorTemplate>
вы можете поместить разделитель.
Оберните элемент управления SiteMapPath тегами <ul>
, и он должен это сделать.
Пример:
<ul class="breadcrumb">
<asp:SiteMapPath ID="SiteMapPath1" PathSeparator="" runat="server">
<NodeTemplate>
<li>
<a href='<%# Eval("url") %>' title='<%# Eval("description") %>'><%# Eval("title") %></a>
</li>
</NodeTemplate>
<PathSeparatorTemplate>
<span class="divider">/</span>
</PathSeparatorTemplate>
</asp:SiteMapPath>
</ul>
Это отличный вариант при использовании Bootstrap и ASP.NET