为umbraco构建一个多级菜单

4 xslt umbraco

我正在尝试为umbraco内容管理系统上的网站构建一个多级dropdrown CSS菜单.

我需要构建它以具有以下结构:

<ul id="nav">
  <li><a href="..">Page #1</a></li>
  <li>
    <a href="..">Page #2</a>
    <ul>
      <li><a href="..">Subpage #1</a></li>
      <li><a href="..">Subpage #2</a></li>        
    </ul>
  </li>
</ul>
Run Code Online (Sandbox Code Playgroud)

所以现在我想弄清楚如何使用XSLT进行嵌套.这是我到目前为止:

<xsl:output method="xml" omit-xml-declaration="yes"/>

<xsl:param name="currentPage"/>

<!-- update this variable on how deep your menu should be -->
<xsl:variable name="maxLevelForMenu" select="4"/>

<xsl:template match="/">
  <ul id="nav">
    <xsl:call-template name="drawNodes">  
      <xsl:with-param 
       name="parent" 
       select="$currentPage/ancestor-or-self::node [@level=1]"
      />  
    </xsl:call-template>
  </ul>
</xsl:template>

<xsl:template name="drawNodes">
  <xsl:param name="parent"/> 
  <xsl:if test="umbraco.library:IsProtected($parent/@id, $parent/@path) = 0 or (umbraco.library:IsProtected($parent/@id, $parent/@path) = 1 and umbraco.library:IsLoggedOn() = 1)">
    <xsl:for-each select="$parent/node [string(./data [@alias='umbracoNaviHide']) != '1' and @level &lt;= $maxLevelForMenu]"> 
      <li>
        <a href="{umbraco.library:NiceUrl(@id)}">
          <xsl:value-of select="@nodeName"/>
        </a>  
        <xsl:if test="count(./node [string(./data [@alias='umbracoNaviHide']) != '1' and @level &lt;= $maxLevelForMenu]) &gt; 0">   
          <xsl:call-template name="drawNodes">    
            <xsl:with-param name="parent" select="."/>    
          </xsl:call-template>  
        </xsl:if> 
      </li>
    </xsl:for-each>
  </xsl:if>
</xsl:template>
Run Code Online (Sandbox Code Playgroud)

我似乎无法弄清楚的是如何检查第一级(这里是第1页和第2页)是否有任何子节点,以及它们是否添加额外的<ul>以包含<li>子节点.

有谁在那里指出我正确的方向?

Tom*_*lak 5

首先,不需要传递parent参数.上下文将传输此信息.

这是应该解决您的问题的XSL样式表:

<!-- update this variable on how deep your menu should be -->
<xsl:variable name="maxLevelForMenu" select="4"/>

<!--- match the document root --->
<xsl:template match="/root">
  <div id="nav">
    <xsl:call-template name="SubTree" />
  </div>
</xsl:template>

<!-- this will be called by xsl:apply-templates -->
<xsl:template match="node">
  <!-- the node is either protected, or the user is logged on (no need to check for IsProtected twice) -->
  <xsl:if test="umbraco.library:IsProtected($parent/@id, $parent/@path) = 0 or umbraco.library:IsLoggedOn() = 1">
    <li>
      <a href="{umbraco.library:NiceUrl(@id)}"><xsl:value-of select="@nodeName"/></a>
      <xsl:call-template name="SubTree" />
    </li>
  </xsl:if>
</xsl:template>

<xsl:template name="SubTree">
  <!-- render sub-tree only if there are any child nodes --->
  <xsl:if test="node">
    <ul>
      <xsl:apply-templates select="node[data[@alias='umbracoNaviHide'] != '1'][@level &lt;= $maxLevelForMenu]">
        <!-- ensure sorted output of the child nodes --->
        <xsl:sort select="@sortOrder" data-type="number" />
      </xsl:apply-templates>
    </ul>
  </xsl:if>
</xsl:template>
Run Code Online (Sandbox Code Playgroud)

这是我测试它的XML(我对Umbraco不太了解,但在查看了一些示例后,我希望我接近Umbraco文档):

<root id="-1">
  <node id="1" level="1" sortOrder="1" nodeName="Page #1">
    <data alias="umbracoNaviHide">0</data>
  </node>
  <node id="2" level="1" sortOrder="2" nodeName="Page #2">
    <data alias="umbracoNaviHide">0</data>
    <node id="3" level="2" sortOrder="2" nodeName="Subpage #2.2">
      <data alias="umbracoNaviHide">0</data>
    </node>
    <node id="4" level="2" sortOrder="1" nodeName="Subpage #2.1">
      <data alias="umbracoNaviHide">0</data>
      <node id="5" level="3" sortOrder="3" nodeName="Subpage #2.1.1">
        <data alias="umbracoNaviHide">0</data>
      </node>
    </node>
    <node id="6" level="2" sortOrder="3" nodeName="Subpage #2.3">
      <data alias="umbracoNaviHide">1</data>
    </node>
  </node>
  <node id="7" level="1" sortOrder="3" nodeName="Page #3">
    <data alias="umbracoNaviHide">1</data>
  </node>
</root>
Run Code Online (Sandbox Code Playgroud)

这是输出:

<div id="nav">
  <ul>
    <li><a href="http://foo/">Page #1</a></li>
    <li><a href="http://foo/">Page #2</a>
      <ul>
        <li><a href="http://foo/">Subpage #2.1</a>
          <ul>
            <li><a href="http://foo/">Subpage #2.1.1</a></li>
          </ul>
        </li>
        <li><a href="http://foo/">Subpage #2.2</a></li>
      </ul>
    </li>
  </ul>
</div>
Run Code Online (Sandbox Code Playgroud)