Вопрос
Я внимательно просмотрел кучу документации MS только для того, чтобы найти древовидную структуру, подобную использованию sitemaps.Я не думаю, что кто-нибудь знает о том, как возможно иметь структуру, подобную папке, для навигации по карте сайта?Возьмем, к примеру, следующую структуру
Home
About
Me.aspx
MyFamily.aspx
MyPets.aspx
Contact
Telephone.aspx
Email.aspx
Disclaimer.aspx
"About" и "Contact" были бы папками, но карта сайта никогда не является иерархической на одной странице.Итак, у меня была бы моя корневая страница с двумя пунктами меню, один из которых был бы "Home", который действует как папка для перехода к меню about и contact, а другой - ссылка на страницу с отказом от ответственности.Я хочу иметь возможность нажать "Главная страница", которая перезагрузит меню со ссылками "О программе" и "Контакт" и полностью скроет "Главная страница" и "Отказ от ответственности".
Home >
Disclaimer
Затем нажмите на главную страницу, и вы получите
About >
Contact >
Затем, нажав на "О программе", вы получите
Me
My Family
My Pets
В каждом меню будет "верхнее" меню для возврата из папки.
Я не вижу простого решения, но на данный момент мы используем статические html-страницы, которые находятся в разных папках по всему нашему веб-приложению.Это то, что нуждается в изменении, как вы хорошо можете себе представить.
Есть какие-нибудь идеи?
Редактировать
Мне пришлось придумать VB.NET решение
<script runat="server">
Private Function GetSecondaryNavItems() As String
Dim sRet As String = ""
Dim oCurrNode As System.Web.SiteMapNode = Nothing
Dim oCurrParentNode As System.Web.SiteMapNode = Nothing
'Dim sCurrPage As String = GetURL(Request.ServerVariables("SCRIPT_NAME").ToLower())
Dim sCurrPage As String = GetURL(HttpContext.Current.Request.ServerVariables("SCRIPT_NAME").ToLower())
oCurrNode = GetCurrentNode(sCurrPage, SiteMap.RootNode)
If Not oCurrNode Is Nothing Then
oCurrParentNode = oCurrNode.ParentNode
End If
If Not oCurrParentNode Is Nothing Then
If Not oCurrParentNode Is SiteMap.RootNode Then
sRet += "Parent Folder Link"
If Not oCurrNode Is Nothing Then
For Each oChild As SiteMapNode In oCurrParentNode.ChildNodes
sRet += "Link for child"
Next
End If
End If
End If
Return sRet
End Function
Private Function GetURL(ByVal fullURL As String) As String
Return fullURL.Substring(fullURL.LastIndexOf("/"))
End Function
Private Function GetCurrentNode(ByVal _sCurrentPageURL As String, ByVal _oNode As SiteMapNode) As SiteMapNode
Dim oNodeRet As SiteMapNode = Nothing
For Each oNodeCheck As SiteMapNode In _oNode.ChildNodes
If oNodeCheck.HasChildNodes = True Then
oNodeRet = GetCurrentNode(_sCurrentPageURL, oNodeCheck)
End If
If oNodeRet Is Nothing Then
Exit For
End If
Dim sURL As String = oNodeCheck.Url.ToLower()
Dim iPos As Integer = sURL.IndexOf("?")
If iPos > 0 Then
sURL = sURL.Substring(0, iPos)
End If
iPos = sURL.LastIndexOf("/")
If iPos > 0 Then
sURL = sURL.Substring(iPos)
End If
If sURL = _sCurrentPageURL Then
oNodeRet = oNodeCheck
Exit For
End If
Next
Return oNodeRet
End Function
</script>
Это находится непосредственно в главном файле страницы (временном, позже я добавлю его в код, лежащий в основе модели).
Затем у меня есть это в теле
<div id="sidebar">
<%= GetSecondaryNavItems() %>
</div>
Опять же, временно, просто для проверки.На самом деле это ничего не выводит, но тогда я думаю, что мое определение getURL неверно.Я предполагал, что это просто получение реального файла?Хотя я могу сильно ошибаться :)
ПРАВИТЬ ПРАВИТЬ:По какой-то причине я не получаю никаких выходных данных, поэтому я подумал, что это моя карта сайта.Мне нужно будет его отладить, но в данный момент я подключаюсь удаленно, так что это довольно медленно ;)
<?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
<siteMapNode url="Accounts/Default.aspx" title="Accounts" description="Accounts">
<siteMapNode url="Accounts/Test.aspx" title="Client Balances" description="Client Balances">
<siteMapNode url="Hello.aspx" title="Hello" description="rarar" />
<siteMapNode url="Hiya.aspx" title="Hiya" description="rarar" />
</siteMapNode>
<siteMapNode url="Test.aspx" title="Test" description="rarar" />
</siteMapNode>
</siteMap>
Вот пример карты сайта.
Решение
Вы все еще можете использовать файл Sitemap.sitemap для управления навигацией, но вы не будете использовать ни один из встроенных элементов управления в asp.net для достижения этой цели.Я только что сделал почти то же самое на сайте, который только что закончил.
Сделайте так, чтобы все ваши страницы наследовались от базового класса page (или используйте master pages, в любом случае у вас будет только 1 копия вашего кода.)
Создайте div или span на каждой странице с подходящим именем (divNav или spnNav или как угодно еще).
На вашей базовой странице при загрузке страницы пройдите по всем узлам sitemap, чтобы найти узел текущей страницы.Это должен быть рекурсивный вызов.
// Pass the current page url, all the way through the .aspx. In other words, do NOT pass any kind of
// query string.
private SiteMapNode GetCurrentNode(string _sCurrentPageURL, SiteMapNode _oNode)
{
SiteMapNode oNodeRet = null;
foreach (SiteMapNode oNodeCheck in _oNode.ChildNodes)
{
if (oNodeCheck.HasChildNodes == true)
{
oNodeRet = GetCurrentNode(_sCurrentPageURL, oNodeCheck);
}
if (oNodeRet != null)
break;
string sUrl = oNodeCheck.Url.ToLower();
int iPos = sUrl.IndexOf("?");
if (iPos > 0)
sUrl = sUrl.Substring(0, iPos);
iPos = sUrl.LastIndexOf("/");
if (iPos > 0)
sUrl = sUrl.Substring(iPos);
if (sUrl == _sCurrentPageURL)
{
oNodeRet = oNodeCheck;
break;
}
}
return oNodeRet;
}
Как только у вас будет текущий узел, получите его родительский.
Добавьте ссылку ("меню вверх, чтобы вернуться к папке", как вы это назвали).
Затем выполните foreach(SiteMapNode в parent.Дочерние узлы).
Добавьте ссылку для каждого из дочерних элементов.
Итак, наш основной вызов, который мы вызывали при каждой загрузке страницы, был примерно таким:
public string GetSecondaryNavItems()
{
string sRet = "";
// Get the node that matches most of this url...
System.Web.SiteMapNode oCurrNode = null;
System.Web.SiteMapNode oCurrParentNode = null;
string sCurrPage = GetURL(Request.ServerVariables["SCRIPT_NAME"].ToLower());
oCurrNode = GetCurrentNode(sCurrPage, SiteMap.RootNode);
if(oCurrNode != null)
oCurrParentNode = oCurrNode.ParentNode;
if(oCurrParentNode != null)
if(oCurrParentNode != SiteMap.RootNode)
sRet += "Parent Folder link";
if(oCurrNode != null)
{
foreach (System.Web.SiteMapNode oChild in oCurrParentNode.ChildNodes)
{
sRet += "Link for child";
}
}
}
Я должен сказать вам, что приведенный выше код частично скопирован, а частично предоставлен мной самостоятельно.Но я бы подумал, что это должно дать вам хорошее начало.
Редактировать:Мне так жаль!Вот процедура getURL...
public string GetURL(string _sURL)
{
string sRet = _sURL;
int iPos = sRet.IndexOf("?");
if (iPos > 0)
sRet = sRet.Substring(0, iPos);
iPos = sRet.LastIndexOf("/");
if (iPos > 0)
sRet = sRet.Substring(iPos);
return sRet;
}
Другие советы
Хотя я не должен отвечать, я бы на самом деле спросил кое-что еще по этому поводу.Можно ли сделать точно то же самое, но используя страницу, которая состоит просто из <ul>
и <li>
элементы?Причина, по которой я спрашиваю, заключается в том, что наша "карта сайта" на самом деле немного более продвинута как с точки зрения безопасности, так и с точки зрения функциональности.Меню, которые мы запускаем, на самом деле имеют динамические выпадающие списки с полями ввода, это то, что не может быть продублировано в карте сайта.
Итак, идея состоит в том, чтобы сделать точно то же самое, за исключением
<ul>
<li>
<ul>
<li></li>
</ul>
</li>
<li></li>
<li></li>
</ul>
вместо этого структура.Корневой узел должен был бы иметь runat="server" на нем, возможно, таким образом вы могли бы обойти все дочерние элементы?Таким образом, я могу поместить все, что угодно, в свой <li>
и </li>
элементы.
Наша безопасность также довольно спорадична, поскольку карта сайта также не обладает тем детализированным контролем, который мы ищем.