Лучшая альтернатива ASP.Web.sitemap от Net на PHP

#php #asp.net

#php #asp.net

Вопрос:

На ASP.Net Обычно я управляю своей основной навигацией, используя стандартный web.sitemap файл, такой как следующий:

 <?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
    <siteMapNode url="~/index.html" title="My Awesome Site">
        <siteMapNode url="~/About/index.html" title="About">
            <siteMapNode url="~/About/Board.html" title="Board"/>
            <siteMapNode url="~/About/Vision.html" title="Vision"/>
            <siteMapNode url="~/About/Mission.html" title="Mission"/>
            <siteMapNode url="~/About/Support.html" title="Support"/>
            <siteMapNode url="~/About/Locations.html" title="Locations"/>
            <siteMapNode url="~/About/Funding-Sources.html" title="Funding Sources"/>
            <siteMapNode url="~/About/Volunteer.html" title="Volunteer"/>
            <siteMapNode url="~/About/Staff.html" title="Staff"/>
        </siteMapNode>
        <siteMapNode url="~/Parents/index.html" title="Parents">
            <siteMapNode url="~/Parents/Child-Development.html" title="Child Development"/>
            <siteMapNode url="~/Parents/Referrals.html" title="Referrals"/>
        </siteMapNode>
        <siteMapNode url="~/Resources/index.html" title="Resources">
            <siteMapNode url="~/Resources/Resource-Library.html" title="Resource Library"/>
            <siteMapNode url="~/Resources/Links.html" title="Links"/>
        </siteMapNode>
    </siteMapNode>
</siteMap>
  

Затем я обычно создаю пользовательский элемент управления для навигации, который я могу использовать SiteMap.CurrentNode и / или SiteMap.CurrentNode.IsDescendantOf , чтобы пометить текущую страницу как «выбранную» или что-то еще. Я ищу что-то подобное для PHP. В ASP classic нам в значительной степени пришлось бы использовать include и кучу if инструкций, которые работают, но как только вы углубляетесь на пару уровней, вы получаете кучу кода. Вероятно, я мог бы создать переменные в верхней части каждой страницы, обозначающие, на каком «разделе», «подразделе» и «странице» мы находимся, но я бы хотел избежать этого, если это возможно.

Я нашел эту ссылку, которая передает данные через строку запроса, но это не вариант.

Если кто-то не знаком с web.sitemap файлом, я могу объяснить это более подробно, если необходимо.

РЕДАКТИРОВАТЬ — Комментарии для @BrandonS

Суть того, что я ищу, — это возможность определить один файл, который представляет страницы моего сайта. ASP.Net использует XML-файл, который удобен для обнаружения некоторых потенциальных ошибок, но не является обязательным. В идеале я бы хотел использовать точно такой же формат файла, который используется ASP.Net, чтобы я мог делиться кодом, но все еще не обязательно.

В ASP.Net используя карту сайта выше, у меня был бы пользовательский элемент управления (в основном прославленный включаемый файл), который выводит <title> тег на каждой странице. На домашней странице он будет выводить только My Awesome Site , на странице About L2 он будет выводить My Awesome Site - About , а на странице Board L3 он будет выводить My Awesome Site - About - Board . Та же идея может быть использована для панировочных сухарей на подстраницах. (Быстро в сторону, для всех моих сайтов страницы существуют только один раз, поэтому у страницы нет шансов иметь двух родителей.)

На ASP.Net при каждом запросе страницы автоматически создается объект SiteMap. (На самом деле я думаю, что его ленивая загрузка означает, что он фактически не создается, если вы не попытаетесь получить доступ, но это происходит прозрачно.) Таким образом, в любой данный момент я могу использовать SiteMap.CurrentNode объект на любой странице, которая существует в файле sitemap. (Если страница не существует в файле sitemap, null возвращается.) Исходя из этого, я могу попросить SiteMap.CurrentNode.ParentNode или я могу пройти SiteMap.CurrentNode.ChildNodes . Я также могу получить SiteMap.RootNode , который представляет корень файла sitemap. Исходя из этого, я могу идти SiteMap.RootNode.ChildNodes , зная, что эти прямые дочерние элементы представляют страницы уровня 2 моего сайта. Затем я могу ходить с этими дочерними элементами по отдельности, зная, что каждый «внук» представляет L3 и так далее.

Итак, используя приведенную выше рекурсию, я мог бы определить основную навигацию моего сайта, пройдя дочерние элементы корневого узла, и если у меня есть выпадающие меню в моей навигации, то я могу перейти к дочерним элементам. Во время прогулки с детьми или внуками я могу устанавливать классы в зависимости от того, SiteMap.CurrentNode равно или происходит от ребенка или внука. Ниже приведен пример на VB.За вычетом того, как я использую карту сайта для построения навигации L2:

     ''//An array that we append potential CSS class names to such as "first" or "active"
    Dim Classes As List(Of String)

    ''//A StringBuild is just an efficient way to work with Strings
    ''//if you are not familiar with it just now that Append() is basically "amp;=" and AppenLine() is basically "amp;= ...n"
    Dim Buf As New StringBuilder()
    Buf.AppendLine("     <ul>")

    ''//Walk the root child nodes, the N variable will be the current ChildNode of the SiteMap.RootNote
    For Each N As SiteMapNode In SiteMap.RootNode.ChildNodes

        ''//For the first and last child we want to add extra classes in case we need to adjust borders, padding, etc
        Classes = New List(Of String)
        If N.PreviousSibling Is Nothing Then
            Classes.Add("first")
        ElseIf N.NextSibling Is Nothing Then
            Classes.Add("last")
        End If

        ''//See if the page being requested is the current child or if the current page is descended from it so that we can mark it as active
        If SiteMap.CurrentNode IsNot Nothing Then
            If SiteMap.CurrentNode.Equals(N) OrElse SiteMap.CurrentNode.IsDescendantOf(N) Then
                Classes.Add("active")
            End If
        End If

        ''//This code below is just for outputting the <li class="..."><a href="...">...</a></li> code

        ''//Write the opening list tag
        Buf.Append("      <li")
        ''//If the above code created any CSS classes append the class attribute and the space-delimited list of classes
        If Classes.Count > 0 Then
            Buf.Append(" class=""" amp; Join(Classes.ToArray(), " ") amp; """")
        End If
        ''//Close the list tag
        Buf.Append(">")

        ''//Append the hyperlink. The "N" object is the current child of the SiteMap.RootNode.ChildNodes
        ''//All SiteMapNode objects have a Url property and a Title property which is defined in the XML file
        Buf.AppendFormat("<a href=""{0}"">{1}</a></li>", N.Url.Replace("/index.html", "/"), HttpUtility.HtmlEncode(N.Title))

        ''//Append a blank line, I like to keep my code formatted nicely
        Buf.AppendLine()
    Next

    ''//Append the closing list tag
    Buf.AppendLine("     </ul>")
  

Дополнительное примечание

Некоторые люди могут подумать, что это излишество, но все это встроено .Net, вот почему я спрашиваю, существует ли что-то для PHP. Я мог бы создать свой собственный, но, очевидно, я хотел бы избежать этого, если это возможно.

Комментарии:

1. Крис, я думаю, что могу помочь, но поскольку в PHP нет прямого порта класса ASP, чтобы направить вас к нужному классу PHP, какие основные функции вы ищете, потому что я знаю 20, которые я использовал, которые удовлетворят большинству спецификаций класса ASP, но если вы собираетесь использовать определенный набор функций, я могу предложить вам лучший вариант. Я думаю, я говорю, что вы хотите, чтобы это делало?

2. Если вы хотите использовать файл, точно такой же, как web.sitemap в ASP, вам нужно будет написать класс для этого. В большинстве фреймворков уже есть что-то встроенное для управления навигацией. Так что, возможно, информация о том, какой фреймворк вы используете, помогла бы. Zend, Symphony, Cake, CodeIgniter?

3. @BrandonS, я ответил выше с некоторыми дополнительными подробностями. @Harmon Wood, я обычно ориентируюсь на Zend framework. Всем, я знаю, что мог бы создать свой собственный код для синтаксического анализа xml, я просто надеюсь не создавать что-то, что кто-то уже сделал, и мои поиски пока ничего не вернули. Кроме того, мне не нужна целая CMS (WordPress, Joomla и т.д.), я просто ищу в основном помощника по навигации.

4. @Джош М., я в основном a . Сетевик, но мне тоже нужно создавать сайты на PHP. Насколько я могу что-то рекомендовать, в конечном счете последнее слово остается за моими клиентами, и иногда PHP — единственный вариант. Я просто пытаюсь посмотреть, есть ли PHP-эквивалент чего-то, что в ASP. Сеть я нахожу очень удобной. Если он не существует, это нормально, я просто хочу знать, прежде чем писать что-то свое. Я не прошу никого писать что-то для меня, я просто хочу знать, существует ли что-то уже.

5. @Крис Хаас: Я понимаю, и я (частично) пошутил. К сожалению, я не могу предложить никакой помощи — все, что я могу сделать, это оставлять бесполезные комментарии. 😉

Ответ №1:

Хм… Насколько я знаю, в PHP нет встроенных решений. Они находятся во множестве фреймворков.

Например, в Zend у нас есть навигационные контейнеры, которые могут хранить все данные в любом выбранном вами формате — например, xml-config. А затем с помощью помощников навигации zend view мы могли бы вывести это в нашем макете или на конкретной странице.

В качестве примера вы могли бы увидеть автоматически переведенный пост об этом здесь.

Комментарии:

1. Спасибо @Alexander, это пока кажется самым близким, я, вероятно, мог бы даже создать mapper между двумя форматами файлов.

2. Еще раз спасибо @Alexander, я собираюсь наградить тебя наградой. Всем остальным спасибо за ваши комментарии и за то, что показали способы, которыми я мог бы создать свой собственный. В конечном счете, мой вопрос заключался в том, существовало ли что-то уже, и ответ @ Alexander лучше всего соответствовал этому счету.

Ответ №2:

Чтобы уточнить, правильно ли я понял вашу цель: вы хотите, чтобы один файл обрабатывал заголовки и родительские элементы всех ваших страниц?

Конечно! htaccess 🙂

 RewriteEngine on
# ROOT
RewriteRule ^me.html$           me.php?title=Home Page [L,QSA]
# ABOUT
RewriteRule ^about/index.html$  about/index.php?parent=Aboutamp;title=About [L,QSA]
RewriteRule ^about/staff.html$  about/staff.php?parent=Aboutamp;title=The Staff [L,QSA]
  

Однако вы не можете использовать HTML-файлы в структуре вашей файловой системы, поскольку она статична. Файлы должны быть на .php, но при конфигурации этого htaccess URL останется .html.

URL about/index.html будет искать about/index.php и передает ему две переменные: parent и title. Файлы php также должны быть организованы в соответствии с вашим каталогом URL, например, index.php , staff.php в /about папке.

В about/index.php файле вы можете выводить:

 <?php
echo $_GET['parent'];
echo "<br />";
echo $_GET['title'];
  

Изучите подробнее htaccess, если моего ответа недостаточно, но я думаю, это то, что вы ищете.

Комментарии:

1. Спасибо @dragonjet, но я не думаю, что это приведет меня туда, куда мне нужно. Это передает переменную, показывающую моего прямого родителя, но она не обрабатывает полную иерархию, не становясь действительно запутанной. web.sitemap Файл, для которого я пытаюсь найти альтернативу, позволяет мне вычислять информацию о родителях, дочерних элементах и братьях-сестрах.

2. О, я понимаю, что для братьев и сестер, родителей и иерархии вы можете захотеть использовать SimpleXML для декодирования этого же файла и использовать встроенные функции библиотеки SimpleXML. Используйте его на всех страницах, предпочтительно, чтобы он был «включен» в виде файла. но это не поможет с заголовками, поэтому используйте его вместе с htaccess выше.