Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Rory 59 posts 84 karma points
    Jul 19, 2011 @ 13:47
    Rory
    0

    Subset of navigation tree

    Hi

    I'm fiddling with XSLT and trying to get a sub navigation tree working.

    I have the usual site structure:

    Home
    - One
    - - Abc
    - - Def
    - - - ZAb
    - - - - HERE  (*we are at this page)
    - - - XBc
    - - Ghi
    - Two
    - - Jkl
    - - Mno
    - Three
    - - Pqr
    - Four

    etc

    I want it to show the following subset of the navigation tree, when we are at "HERE" page

    - One
    - - Abc
    - - Def
    - - - ZAb
    - - - - HERE  (*we are at this page)
    - - - XBc
     

    I am using the following XSLT

    <?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 omit-xml-declaration="yes" indent="yes" encoding="utf-8"/>
    <xsl:param name="currentPage"/> 
    <xsl:param name="level" select="2"/>
    <!-- stop loop at level: -->  
    <xsl:variable name="maxLevel" select="4" />   
    <xsl:template match="/">   
     <xsl:call-template name="drawNodes">          
      <xsl:with-param name="parent" select="$currentPage/ancestor-or-self::* [@isDoc and @level=$level]"/>       
     </xsl:call-template>   
     
    </xsl:template>   
    <xsl:template name="drawNodes">    
     <xsl:param name="parent"/>   
     <xsl:if test="$parent/@level &lt; $maxLevel">     
     <ul class="clear">       
      <xsl:for-each select="$parent/* [@isDoc and string(umbracoNaviHide) != '1']">         
       <li> 
        <xsl:if test="$currentPage/ancestor-or-self::*/@id = current()/@id"> <!-- We're here, or under here -->
             <xsl:attribute name="class">current1</xsl:attribute>
        </xsl:if>   
        <a href="{umbraco.library:NiceUrl(@id)}">             
         <xsl:value-of select="@nodeName" />           
        </a>           
        <!-- check if there is another level - if so run through again -->           
        <xsl:if test="count(./* [@isDoc and string(umbracoNaviHide) != '1']) &gt; 0 and $currentPage/ancestor-or-self::*/@id = current()/@id">                
         <xsl:call-template name="drawSubNodes">                   
          <xsl:with-param name="parent" select="."/>                 
         </xsl:call-template>             
        </xsl:if>  
       </li>  
      </xsl:for-each>
      </ul> 
     </xsl:if>
    </xsl:template>
    <xsl:template name="drawSubNodes">    
     <xsl:param name="parent"/>   
     <xsl:if test="$parent/@level &lt; $maxLevel">     
     <ul class="level{$level}">
      <xsl:for-each select="$parent/* [@isDoc and string(umbracoNaviHide) != '1']">         
       <li>           
        <xsl:if test="$currentPage/ancestor-or-self::*/@id = current()/@id"> <!-- We're here, or under here -->
             <xsl:attribute name="class">current1</xsl:attribute>
        </xsl:if>
        <a href="{umbraco.library:NiceUrl(@id)}">              
         <xsl:value-of select="@nodeName" />           
        </a>           
        <!-- check if there is another level - if so run through again -->           
        <xsl:if test="count(./* [@isDoc and string(umbracoNaviHide) != '1']) &gt; 0 and $currentPage/ancestor-or-self::*/@id = current()/@id">                
         <xsl:call-template name="drawSubSubNodes">                   
          <xsl:with-param name="parent" select="."/>                 
         </xsl:call-template>             
        </xsl:if>  
       </li>  
      </xsl:for-each>
      </ul> 
     </xsl:if>
    </xsl:template>
    <xsl:template name="drawSubSubNodes">    
     <xsl:param name="parent"/>   
     <xsl:if test="$parent/@level &lt; $maxLevel">     
     <ul class="level{$level}">
      <xsl:for-each select="$parent/* [@isDoc and string(umbracoNaviHide) != '1']">         
       <li>           
        <xsl:if test="$currentPage/ancestor-or-self::*/@id = current()/@id"> <!-- We're here, or under here -->
             <xsl:attribute name="class">current</xsl:attribute>
        </xsl:if>
        <a href="{umbraco.library:NiceUrl(@id)}">              
         <xsl:value-of select="@nodeName" />           
        </a>           
        <!-- check if there is another level - if so run through again -->           
        <xsl:if test="count(./* [@isDoc and string(umbracoNaviHide) != '1']) &gt; 0 and $currentPage/ancestor-or-self::*/@id = current()/@id">                
         <xsl:call-template name="drawSubNodes">                   
          <xsl:with-param name="parent" select="."/>                 
         </xsl:call-template>             
        </xsl:if>  
       </li>  
      </xsl:for-each>
      </ul> 
     </xsl:if>
    </xsl:template>
    </xsl:stylesheet>

    The problem is it is displaying just

    - - Def
    - - - ZAb
    - - - - HERE  (*we are at this page)

    when the level starts at 2.

    If I change the level to start at 1 it displays the entire tree, not just the subset of "One" and children (plus grandchildren).

    Any suggestions please?

    Thanks

    Rory

     

     

  • Rory 59 posts 84 karma points
    Jul 19, 2011 @ 13:49
    Rory
    0

    Just to add, I want it to show the whole subset of "One" regardless of where we are within that section. I'll be adding "current" attribute to the <li> tag for each of the current items.

    Thanks

  • Rory 59 posts 84 karma points
    Jul 26, 2011 @ 13:59
    Rory
    0

    I've solved it by using the following code...someone else may find it useful.

     <?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 omit-xml-declaration="yes" indent="yes" encoding="utf-8"/>
    <xsl:param name="currentPage"/> 
    <xsl:param name="level" select="1"/>

    <!-- stop loop at level: --> 
    <xsl:variable name="maxLevel" select="5" />   
    <xsl:template match="/">   

     <xsl:call-template name="drawLevel1Nodes">         
      <xsl:with-param name="parent" select="$currentPage/ancestor-or-self::* [@isDoc and @level=$level]"/>       
     </xsl:call-template>   
     
    </xsl:template>   

    <xsl:template name="drawLevel1Nodes">   
     <xsl:param name="parent"/>   
     <xsl:if test="$parent/@level &lt; $maxLevel">     
      <ul class="clear">       
       <xsl:for-each select="$parent/* [@isDoc]">   
        <xsl:if test="$currentPage/ancestor-or-self::*/@id = current()/@id"> <!-- We're here, or under here -->
         <li>
          <xsl:choose>
            <xsl:when test="$currentPage/self::*/@id = current()/@id"> <!-- We're here -->
            <xsl:attribute name="class">current1</xsl:attribute>
            </xsl:when>
            <xsl:when test="$currentPage/ancestor::*/@id = current()/@id"> <!-- We're under here -->
            <xsl:attribute name="class">current1</xsl:attribute>
            </xsl:when>
            <xsl:otherwise>     <!-- We're not (under) here -->
            <xsl:attribute name="class"></xsl:attribute>
            </xsl:otherwise>
          </xsl:choose>
          <a href="{umbraco.library:NiceUrl(@id)}">             
           <xsl:value-of select="@nodeName" />           
          </a>           
          <!-- check if there is another level - if so run through again -->           
          <xsl:if test="count(./* [@isDoc and string(umbracoNaviHide) != '1']) &gt; 0 and $currentPage/ancestor-or-self::*/@id = current()/@id">                
           <xsl:call-template name="drawLevel2Nodes">                   
            <xsl:with-param name="parent" select="."/>                 
           </xsl:call-template>             
          </xsl:if>
         </li>
        </xsl:if>
       </xsl:for-each>
      </ul> 
     </xsl:if>
    </xsl:template>

    <xsl:template name="drawLevel2Nodes">   
     <xsl:param name="parent"/>   
     <xsl:if test="$parent/@level &lt; $maxLevel">     
     <ul class="level2">
      <xsl:for-each select="$parent/* [@isDoc and string(umbracoNaviHide) != '1']">         
       <li>
        <xsl:choose>
          <xsl:when test="$currentPage/self::*/@id = current()/@id"> <!-- We're here -->
          <xsl:attribute name="class">current</xsl:attribute>
          </xsl:when>
          <xsl:when test="$currentPage/ancestor::*/@id = current()/@id"> <!-- We're under here -->
          <xsl:attribute name="class">current1</xsl:attribute>
          </xsl:when>
          <xsl:otherwise>     <!-- We're not (under) here -->
          <xsl:attribute name="class"></xsl:attribute>
          </xsl:otherwise>
        </xsl:choose>
        <a href="{umbraco.library:NiceUrl(@id)}">             
         <xsl:value-of select="@nodeName" />           
        </a>           
        <!-- check if there is another level - if so run through again -->           
        <xsl:if test="count(./* [@isDoc and string(umbracoNaviHide) != '1']) &gt; 0 and $currentPage/ancestor-or-self::*/@id = current()/@id">                
         <xsl:call-template name="drawLevel3Nodes">                   
          <xsl:with-param name="parent" select="."/>                 
         </xsl:call-template>             
        </xsl:if>
       </li>   
      </xsl:for-each>
      </ul> 
     </xsl:if>
    </xsl:template>

    <xsl:template name="drawLevel3Nodes">   
     <xsl:param name="parent"/>   
     <xsl:if test="$parent/@level &lt; $maxLevel">     
     <ul class="level3">
      <xsl:for-each select="$parent/* [@isDoc and string(umbracoNaviHide) != '1']">         
       <li>
        <xsl:choose>
          <xsl:when test="$currentPage/self::*/@id = current()/@id"> <!-- We're here -->
          <xsl:attribute name="class">current</xsl:attribute>
          </xsl:when>
          <xsl:when test="$currentPage/ancestor::*/@id = current()/@id"> <!-- We're under here -->
          <xsl:attribute name="class">current1</xsl:attribute>
          </xsl:when>
          <xsl:otherwise>     <!-- We're not (under) here -->
          <xsl:attribute name="class"></xsl:attribute>
          </xsl:otherwise>
        </xsl:choose>
        <a href="{umbraco.library:NiceUrl(@id)}">             
         <xsl:value-of select="@nodeName" />           
        </a>           
        <!-- check if there is another level - if so run through again -->           
        <xsl:if test="count(./* [@isDoc and string(umbracoNaviHide) != '1']) &gt; 0 and $currentPage/ancestor-or-self::*/@id = current()/@id">                
         <xsl:call-template name="drawLevel4Nodes">                   
          <xsl:with-param name="parent" select="."/>                 
         </xsl:call-template>             
        </xsl:if>
       </li>   
      </xsl:for-each>
      </ul> 
     </xsl:if>
    </xsl:template>

    <xsl:template name="drawLevel4Nodes">   
     <xsl:param name="parent"/>   
     <xsl:if test="$parent/@level &lt; $maxLevel">     
     <ul class="level3">
      <xsl:for-each select="$parent/* [@isDoc and string(umbracoNaviHide) != '1']">         
       <li>           
        <xsl:choose>
          <xsl:when test="$currentPage/self::*/@id = current()/@id"> <!-- We're here -->
          <xsl:attribute name="class">current</xsl:attribute>
          </xsl:when>
          <xsl:when test="$currentPage/ancestor::*/@id = current()/@id"> <!-- We're under here -->
          <xsl:attribute name="class">current1</xsl:attribute>
          </xsl:when>
          <xsl:otherwise>     <!-- We're not (under) here -->
          <xsl:attribute name="class"></xsl:attribute>
          </xsl:otherwise>
        </xsl:choose>
        <a href="{umbraco.library:NiceUrl(@id)}">             
         <xsl:value-of select="@nodeName" />           
        </a>           
        <!-- check if there is another level - if so run through again -->           
        <xsl:if test="count(./* [@isDoc and string(umbracoNaviHide) != '1']) &gt; 0 and $currentPage/ancestor-or-self::*/@id = current()/@id">                
         <xsl:call-template name="drawLevel4Nodes">                   
          <xsl:with-param name="parent" select="."/>                 
         </xsl:call-template>             
        </xsl:if>
       </li>      
      </xsl:for-each>
      </ul> 
     </xsl:if>
    </xsl:template>
    </xsl:stylesheet>

Please Sign in or register to post replies

Write your reply to:

Draft