A very standard left expanding/folding menu for umbraco Options
cdj
Posted: Tuesday, December 18, 2007 2:22:12 PM
Rank: Newbie

Joined: 12/18/2007
Posts: 2
I thought it was strangely difficult to find a good XSLT document for creating a standard expanding left menu for the web site. This menu keeps the home page in the same level as the first sub level and always in the top row. Only levels in the "active" sub-tree are exposed and folding/unfolding only occurs while navigating.

Here is the xslt:

<?xml version="1.0" encoding="utf-8"?>
<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="html"/>
<xsl:param name="currentPage"/>

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

<xsl:template name="drawNodes">
<xsl:param name="current"/>
<xsl:param name="openpage"/>
<xsl:param name="level"/>
<xsl:param name="active">
<xsl:choose>
<xsl:when test="count($openpage/ancestor-or-self::node) &gt; 0">
<xsl:call-template name="isInSubmenu">
<xsl:with-param name="list" select="$openpage/ancestor-or-self::node"/>
<xsl:with-param name="pos" select="1"/>
<xsl:with-param name="curpagename" select="$current/@id"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
1
</xsl:otherwise>
</xsl:choose>
</xsl:param>
<xsl:if test="$active=1">
<ul class="menu">
<xsl:if test="$level = 1">
<li class="menu level1">
<a href="/" class="menu">Home Page</a>
</li>
</xsl:if>
<xsl:for-each select="$current/node [string(data [@alias='umbracoNaviHide']) != '1']">
<li class="menu level{$level}">
<xsl:choose>
<xsl:when test="@id=$openpage/@id">
<a href="{umbraco.library:NiceUrl(@id)}" class="menu selected">
<xsl:value-of select="@nodeName"/>
</a>
</xsl:when>
<xsl:otherwise>
<a href="{umbraco.library:NiceUrl(@id)}" class="menu">
<xsl:value-of select="@nodeName"/>
</a>
</xsl:otherwise>
</xsl:choose>
<xsl:call-template name="drawNodes">
<xsl:with-param name="current" select="."/>
<xsl:with-param name="openpage" select="$openpage"/>
<xsl:with-param name="level" select="$level + 1"/>
</xsl:call-template>
</li>
</xsl:for-each>
</ul>
</xsl:if>
</xsl:template>

<xsl:template name="isInSubmenu">
<xsl:param name="list"/>
<xsl:param name="pos"/>
<xsl:param name="curpagename"/>
<xsl:variable name="curitemname" select="$list[$pos]/@id"/>
<xsl:choose>
<xsl:when test="$curitemname != $curpagename">
<xsl:choose>
<xsl:when test="$pos &lt; count($list)">
<xsl:call-template name="isInSubmenu">
<xsl:with-param name="list" select="$list"/>
<xsl:with-param name="pos" select="$pos + 1"/>
<xsl:with-param name="curpagename" select="$curpagename"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
0
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
1
</xsl:otherwise>
</xsl:choose>
</xsl:template>

</xsl:stylesheet>
cdj
Posted: Tuesday, December 18, 2007 2:24:35 PM
Rank: Newbie

Joined: 12/18/2007
Posts: 2
And with a code tag...

Code:

<?xml version="1.0" encoding="utf-8"?>
<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="html"/>
  <xsl:param name="currentPage"/>

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

  <xsl:template name="drawNodes">
    <xsl:param name="current"/>
    <xsl:param name="openpage"/>
    <xsl:param name="level"/>
    <xsl:param name="active">
      <xsl:choose>
        <xsl:when test="count($openpage/ancestor-or-self::node) &gt; 0">
          <xsl:call-template name="isInSubmenu">
            <xsl:with-param name="list" select="$openpage/ancestor-or-self::node"/>
            <xsl:with-param name="pos" select="1"/>
            <xsl:with-param name="curpagename" select="$current/@id"/>
          </xsl:call-template>
        </xsl:when>
        <xsl:otherwise>
          1
        </xsl:otherwise>
      </xsl:choose>
    </xsl:param>
    <xsl:if test="$active=1">
      <ul class="menu">
        <xsl:if test="$level = 1">
          <li class="menu level1">
            <a href="/" class="menu">Home Page</a>
          </li>
        </xsl:if>
        <xsl:for-each select="$current/node [string(data [@alias='umbracoNaviHide']) != '1']">
          <li class="menu level{$level}">
            <xsl:choose>
              <xsl:when test="@id=$openpage/@id">
                <a href="{umbraco.library:NiceUrl(@id)}" class="menu selected">
                  <xsl:value-of select="@nodeName"/>
                </a>
              </xsl:when>
              <xsl:otherwise>
                <a href="{umbraco.library:NiceUrl(@id)}" class="menu">
                  <xsl:value-of select="@nodeName"/>
                </a>
              </xsl:otherwise>
            </xsl:choose>
            <xsl:call-template name="drawNodes">
              <xsl:with-param name="current" select="."/>
              <xsl:with-param name="openpage" select="$openpage"/>
              <xsl:with-param name="level" select="$level + 1"/>
            </xsl:call-template>
          </li>
        </xsl:for-each>
      </ul>
    </xsl:if>
  </xsl:template>

  <xsl:template name="isInSubmenu">
    <xsl:param name="list"/>
    <xsl:param name="pos"/>
    <xsl:param name="curpagename"/>
    <xsl:variable name="curitemname" select="$list[$pos]/@id"/>
    <xsl:choose>
      <xsl:when test="$curitemname != $curpagename">
        <xsl:choose>
          <xsl:when test="$pos &lt; count($list)">
            <xsl:call-template name="isInSubmenu">
              <xsl:with-param name="list" select="$list"/>
              <xsl:with-param name="pos" select="$pos + 1"/>
              <xsl:with-param name="curpagename" select="$curpagename"/>
            </xsl:call-template>
          </xsl:when>
          <xsl:otherwise>
            0
          </xsl:otherwise>
        </xsl:choose>
      </xsl:when>
      <xsl:otherwise>
        1
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

</xsl:stylesheet>
readingdancer
Posted: Tuesday, December 18, 2007 4:54:22 PM

Rank: Enthusiast

Joined: 9/27/2007
Posts: 24
Location: Reading, UK
Hi Christoffer,

I might be missing something by your XSLT actually looks over complicated. I'm pretty sure you can create the same menu using the following XSLT.

Code:
<?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:variable name="level" select="1"/>

<xsl:template match="/">

<div class="navtree">
<ul><li><a href="/">Home</a></li></ul>
<xsl:call-template name="printListe">
    <xsl:with-param name="node" select="$currentPage/ancestor-or-self::node [@level = 1]"/>    
    <xsl:with-param name="id" select="string('treemenu1')"/>    
</xsl:call-template>
</div>
</xsl:template>

<xsl:template name="printListe">
<xsl:param name="node"/>
<xsl:param name="id"/>

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


I use the above on our site for a top menu, but you could just modify the CSS to display the menu on the left. On our site I have also wrapped the menu in a table so that I could add the silly little corner graphics ;) I have remove that from the above XSLT.

You can see the menu on our site: http://Added Value Applications Ltd

Best regards,

Chris

Chris Houston - Business Dev Director for Ava / CTO for Clik Media Group / Umbraco Developer
Users browsing this topic
Guest


You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.