简体   繁体   English

PHP 中 ASP.Net 的 web.sitemap 的最佳替代品

[英]Best alternative to ASP.Net's web.sitemap in PHP

In ASP.Net I usually drive my primary navigation using a standard web.sitemap file such as the following:在 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>

Then I usually create a user control for the navigation where I can use SiteMap.CurrentNode and/or SiteMap.CurrentNode.IsDescendantOf to mark the current page as "selected" or whatever.然后我通常为导航创建一个用户控件,我可以在其中使用SiteMap.CurrentNode和/或SiteMap.CurrentNode.IsDescendantOf将当前页面标记为“选定”或其他任何内容。 I'm looking for something similar for PHP.我正在为 PHP 寻找类似的东西。 In ASP classic we would pretty much have to use an include and a bunch of if statements which works but once you get a couple of levels deep you end up with a bunch of code.在 ASP 经典中,我们几乎必须使用包含和一堆if语句,但一旦你深入到几个级别,你最终会得到一堆代码。 I could probably create variables at the top of each page designating which "section", "subsection" and "page" we're on but I'd like to avoid that if possible.我可能会在每个页面的顶部创建变量来指定我们所在的“部分”、“子部分”和“页面”,但如果可能的话,我想避免这种情况。

I found this link which bounces things through the querystring but that's not an option.我发现这个链接通过查询字符串反弹了东西,但这不是一个选项。

If anyone's not familiar with the web.sitemap file I can explain it in more detail if needed.如果有人不熟悉web.sitemap文件,如果需要,我可以更详细地解释它。

EDIT - Comments for @BrandonS编辑-@BrandonS 的评论

The core of what I'm looking for is to be able to define a single file that represents the pages of my site.我正在寻找的核心是能够定义一个代表我网站页面的文件。 ASP.Net uses an XML file which is convenient for catching some potential errors but isn't required. ASP.Net 使用 XML 文件,它便于捕获一些潜在的错误,但不是必需的。 Ideally I'd actually like to use exact same file format used by ASP.Net so that I can share code but still not absolutely required.理想情况下,我实际上希望使用 ASP.Net 使用的完全相同的文件格式,以便我可以共享代码,但仍然不是绝对必需的。

In ASP.Net, using the sitemap above I would have a user control (basically a glorified include file) that outputs the <title> tag on every page.在 ASP.Net 中,使用上面的站点地图,我将有一个用户控件(基本上是一个美化的包含文件),它在每个页面上输出<title>标记。 On the Home page it would output just My Awesome Site , on the About L2 page it would output My Awesome Site - About and on the Board L3 page it would output My Awesome Site - About - Board .主页上,它会 output 只是My Awesome Site ,在About L2 页面上,它会 output My Awesome Site My Awesome Site - About - Board My Awesome Site - AboutBoard L3 页面上,它会 Z78E6221F6393D1356681DB398F14CE。 The same idea might be used for breadcrumbs on subpages.相同的想法可能用于子页面上的面包屑。 (Quick aside, for all of my sites pages exist only once so there's no chance of a page having two parents.) (顺便说一句,因为我所有的网站页面都只存在一次,所以一个页面不可能有两个父母。)

In ASP.Net on every page request a SiteMap object gets automatically created.在 ASP.Net 中,每个页面请求都会自动创建一个 SiteMap object。 (Actually I think its lazy-loaded meaning it actually doesn't get created unless you try accessing but that happens transparently.) So at any given moment I can use a SiteMap.CurrentNode object on any page that exists in the sitemap file. (实际上,我认为它的延迟加载意味着它实际上不会被创建,除非您尝试访问但这是透明地发生的。)因此,在任何给定时刻,我都可以在站点地图文件中存在的任何页面上使用SiteMap.CurrentNode object。 (If the page doesn't exist in the sitemap file null is returned.) From that I can ask for the SiteMap.CurrentNode.ParentNode or I can walk the SiteMap.CurrentNode.ChildNodes . (如果站点地图文件null中不存在该页面,则返回。)从那里我可以要求SiteMap.CurrentNode.ParentNode或者我可以走SiteMap.CurrentNode.ChildNodes I can also get the SiteMap.RootNode which represents the root of the sitemap file.我还可以获得代表站点地图文件根的SiteMap.RootNode From that I can walk the SiteMap.RootNode.ChildNodes knowing that these direct children represent the Level 2 pages of my site.从那里我可以知道这些直接子节点代表我网站的第 2 级页面,因此我可以遍历SiteMap.RootNode.ChildNodes I can then walk these children individually knowing that each "grandchild" represents an L3 and so on.然后,我可以知道每个“孙子”代表一个 L3 等等,从而单独引导这些孩子。

So using the above recursion I could define my site's primary navigation by walking the root node's children and if I've got dropdown menus in my nav then I can walk the sub-children.因此,使用上面的递归,我可以通过遍历根节点的子节点来定义我的站点的主导航,如果我的导航中有下拉菜单,那么我可以遍历子节点。 While walking the children or grandchildren I can set classes based on if the SiteMap.CurrentNode equals or is descended from the child or grandchild.在带孩子或孙子走路时,我可以根据SiteMap.CurrentNode等于孩子或孙子的后代来设置类。 Below is an example in VB.Net of how I use the sitemap for building an L2 navigation:下面是 VB.Net 中我如何使用站点地图构建 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 "&=" and AppenLine() is basically "&= ...\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=""" & Join(Classes.ToArray(), " ") & """")
        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>")

Additional note附加说明

Some people might think that this is overkill but this is all built into.Net, that's why I'm asking if something exists for PHP.有些人可能认为这有点矫枉过正,但这都是内置在.Net中的,这就是为什么我要问PHP是否存在某些东西。 I could roll my own but obviously I'd like to avoid it if possible.我可以自己动手,但显然我想尽可能避免。

Hmm... As I know, there are no built-in solutions in PHP.嗯...据我所知,PHP 中没有内置解决方案。 They are in a plenty of frameworks.它们存在于许多框架中。

For example in Zend we have navigation containers , that could store all data in any format you choose -- xml-config for example.例如,在 Zend 中,我们有导航容器,它可以以您选择的任何格式存储所有数据——例如 xml-config。 And then with help of zend view navigation helpers we could output it in our layout or in concrete page.然后在zend 视图导航助手的帮助下,我们可以在我们的布局或具体页面中 output 它。

As an example you could see autotranslated post about it here .例如,您可以在此处看到关于它的自动翻译帖子。

To clarify if I understood your goal correctly: is that you want a single file to handle all your pages' titles and parents?为了澄清我是否正确理解了您的目标:您是否想要一个文件来处理所有页面的标题和父级?

Of Course: htaccess :)当然:htaccess :)

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

However you cannot use.html files in your filesystem structure because it is static.但是,您不能在文件系统结构中使用.html 文件,因为它是 static。 The files need to be in.php, but with the configuration of that htaccess, the URL will be remain.html.这些文件需要在.php 中,但是通过该 htaccess 的配置,URL 将保留在.html。

The URL about/index.html will look for about/index.php and passes two variables to it: parent and title. URL about/index.html将查找about/index.php并向其传递两个变量:父级和标题。 The php files will also need to be organized according to your URL directory like index.php , staff.php in /about folder. The php files will also need to be organized according to your URL directory like index.php , staff.php in /about folder.

In the about/index.php file, you can output:about/index.php文件中,可以output:

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

Research more on htaccess if my answer is insufficient, but I think this is what you're looking for.如果我的答案不充分,请对 htaccess 进行更多研究,但我认为这就是您要寻找的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM