15 January 2010 ~ 2 Comments

Recursive Navigation in Umbraco

A recursive call in XSLT can be a bit confusing. It was for me. Here is a simple stylesheet that gets all nodes in this section (Usually a section in Umbraco sits underneath the Hompage, e.g. Content -> Homepage -> Section 1).

[codesyntax lang="xml"]

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xsl:stylesheet [
  <!ENTITY nbsp "&#x00A0;">
]>
<xsl:stylesheet
	version="1.0"
	xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
	xmlns:msxml="urn:schemas-microsoft-com:xslt"
	xmlns:umbraco.library="urn:umbraco.library"
	exclude-result-prefixes="msxml umbraco.library">

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

  <xsl:param name="currentPage"/>

  <xsl:param name="level" select="2"/>

  <xsl:template match="/">
    <xsl:call-template name="menu">
      <xsl:with-param name="level" select="$level"/>
    </xsl:call-template>
  </xsl:template>

  <xsl:template name="menu">
    <xsl:param name="level"/>

    <ul class="level_{@level}">
      <xsl:if test="count($currentPage/ancestor-or-self::node [@level=$level]/node [string(data [@alias='umbracoNaviHide']) != '1']) &gt; '0'">
        <xsl:for-each select="$currentPage/ancestor-or-self::node [@level=$level]/node [string(data [@alias='umbracoNaviHide']) != '1']">
          <li>
              <a href="{umbraco.library:NiceUrl(@id)}">
                <xsl:if test="$currentPage/@id = current()/@id">
                  <xsl:attribute name="class">Selected</xsl:attribute>
                </xsl:if>
                <xsl:value-of select="@nodeName"/>
              </a>
            <xsl:if test="count(current()/node [string(data [@alias='umbracoNaviHide']) != '1']) &gt; '0'">
              <xsl:call-template name="submenu">
                <xsl:with-param name="level" select="$level+1"/>
              </xsl:call-template>
            </xsl:if>
          </li>
        </xsl:for-each>
      </xsl:if>
    </ul>
  </xsl:template>

  <xsl:template name="submenu">
    <xsl:param name="level"/>

    <ul class="level_{@level}">
      <xsl:for-each select="current()/node [string(data [@alias='umbracoNaviHide']) != '1']">
        <li>
            <a href="{umbraco.library:NiceUrl(@id)}">
              <xsl:if test="$currentPage/@id = current()/@id">
                <xsl:attribute name="class">Selected</xsl:attribute>
              </xsl:if>
              <xsl:value-of select="@nodeName"/>
            </a>
          <xsl:if test="count(current()/node [string(data [@alias='umbracoNaviHide']) != '1']) &gt; '0'">
            <xsl:call-template name="submenu">
              <xsl:with-param name="level" select="$level+1"/>
            </xsl:call-template>
          </xsl:if>
        </li>
      </xsl:for-each>
    </ul>
  </xsl:template>

</xsl:stylesheet>

[/codesyntax]

This code also adds a class to the node you are currently visiting.

2 Responses to “Recursive Navigation in Umbraco”

  1. Jason 20 January 2010 at 12:58 am Permalink

    Looks great.

    This can be tricky and I find that I’m always copy/pasting from previous projects so I don’t have redo all of that logic.

  2. Bram 19 February 2010 at 12:18 pm Permalink

    very clear example showing the power of XSLT.
    thx


Leave a Reply