Copied to clipboard

Flag this post as spam?

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


  • Martin 278 posts 662 karma points
    Jan 24, 2012 @ 15:24
    Martin
    0

    Loop & Group Navigation List - Mega Menu

    Hi,
    Im having some issues with looping and applying a list to my menu structure.
    I want to group the sub-pages into 5 items with a <ul> tag. So my html would be,

    <ul class="nav">
    <li>Heading<li>
      <li>Heading
        <ul class="sub-page">
    <ul class="sub-page-group first-group">
    <li>Item</li>
    <li>Item</li> <li>Item</li> <li>Item</li> <li>Item</li> </ul> <ul class="sub-page-group second-group">
    <li>Item</li>
    <li>Item</li>
    </ul>     </ul>
      <li>

     

    I've had a look through the forum to find something similar and found some xslt, which ive applied.
    But im getting some strange html output, with empty <ul> and <li> produced.

    Any help would be grateful.

    The XSLT that Ive added is:

        <!--DROP DOWN NAVIGATION-->    
        <xsl:if test="*[umbracoNaviHide != 1]">
          <ul>
            <xsl:for-each select="* [position() mod 5 = 1]">
            <ul class="drop-group">
            <xsl:for-each select=". | following-sibling::*[not(position() >= 5)]">
              <li class="drop-item">
                <xsl:value-of select="@nodeName" />
              </li>
            </xsl:for-each>
          </ul>
        </xsl:for-each>  

    My full XSLT is

      <xsl:template match="/">  
        <!-- Root Node -->
        <xsl:variable name="rootNode" select="$currentPage/ancestor-or-self::root" />
        <!-- Homepage -->
        <xsl:variable name="homeNode" select="$rootNode/Home [@isDoc]" />    
        <ul>
          <li>
            <!-- Add the CSS class 'selected' if the homeNode ID matches our currentPage node ID
            -->
            <xsl:if test="$homeNode/@id = $currentPage/@id">
              <xsl:attribute name="class">
                <xsl:text>selected</xsl:text>
              </xsl:attribute>
            </xsl:if>       
            <!--Create a link to the homepage -->
            <href="{umbraco.library:NiceUrl($homeNode/@id)}">
              <xsl:value-of select="$homeNode/@nodeName" />
            </a>
          </li>  
          
        <!--For each child node of the homeNode that is a document (isDoc)and the level is 2 and the property umbracoNaviHide is NOT 1 (true/checked)-->
        <xsl:for-each select="$homeNode/*[@level = 2][umbracoNaviHide != 1]">         
        <li class="{@urlName}">          
        <xsl:if test="$currentPage/ancestor-or-self::*[@isDoc]/@id = current()/@id">
          <xsl:attribute name="class"><xsl:value-of select="concat(@urlName, ' selected')"/></xsl:attribute>
        </xsl:if>
         <xsl:if test="position() = last()">
            <xsl:attribute name="id">
              <xsl:text>last</xsl:text>
            </xsl:attribute>
          </xsl:if>
        <xsl:if test="umbraco.library:HasAccess(@id,@path)">
        <!-- Create the link -->
        <href="{umbraco.library:NiceUrl(@id)}"><xsl:value-of select="@nodeName" /></a>
        </xsl:if>
        
        <!--DROP DOWN NAVIGATION-->    
        <xsl:if test="*[umbracoNaviHide != 1]">
          <ul>
            <xsl:for-each select="* [position() mod 5 = 1]">
            <ul class="drop-group">
            <xsl:for-each select=". | following-sibling::*[not(position() >= 5)]">
              <li class="drop-item">
                <xsl:value-of select="@nodeName" />
              </li>
            </xsl:for-each>
          </ul>
        </xsl:for-each>        
            
          </ul>
        </xsl:if>    
        </li>
      </xsl:for-each>
      </ul>
      </xsl:template>

  • Rodion Novoselov 694 posts 859 karma points
    Jan 24, 2012 @ 15:47
    Rodion Novoselov
    0

    There're several way to do it. Personally I usually do it with such a snippet (I'm skipping the outer <ul> and so on for brevity) :

    <xsl:foreach select="$nodes">
      <xsl:if test="position() mod $N = 1">
           <xsl:value-of disable-output-escaping="yes">
               <![CDATA[<ul>]]>
           </xsl:value-of>
      </xsl:if>
      <li>
           <xsl:value-of select="@nodeName"/>
      </li>
      <xsl:if test="position() mod $N = 0 or position() = last()">         <xsl:value-of disable-output-escaping="yes"> 
               <![CDATA[</ul>]]>
           </xsl:value-of> 
       <xsl:if>
    </xsl:foreach>

    I hope it will help.

  • Martin 278 posts 662 karma points
    Jan 24, 2012 @ 16:50
    Martin
    0

    Thanks Rodion, Im getting a little lost on the xslt. Im just getting to grips with xslt.

    Ive added the the following variables with the following code, but im getting an error

    Missing mandatory attribute 'select'.

     

      <xsl:variable name="nodes" select="$currentPage/ancestor-or-self::node"/>  
      <xsl:variable name="N" select="$nodes" />

    <!-- DROP DOWN -->

    <xsl:for-eachselect="$nodes">
       
    <xsl:iftest="position() mod $N = 1">
           
    <xsl:value-ofdisable-output-escaping="yes">
               <![CDATA[
    <ul>]]>
           
    </xsl:value-of>
       
    </xsl:if>
       
    <li>
           
    <xsl:value-ofselect="@nodeName"/>
       
    </li>
       
    <xsl:iftest="position() mod $N = 0 or position() = last()">        
           
    <xsl:value-ofdisable-output-escaping="yes">
               <![CDATA[
    </ul>]]>
           
    </xsl:value-of>
       
    </xsl:if>
    </xsl:for-each>
  • Rodion Novoselov 694 posts 859 karma points
    Jan 24, 2012 @ 17:13
    Rodion Novoselov
    1

    Sorry. My fault. Rewrite both "xsl:value-of" as:

    <xsl:value-of select="'&lt;ul&gt;'" disable-output-escaping="yes"/>

    and

    <xsl:value-of select="'&lt;/ul&gt;'" disable-output-escaping="yes"/>

    (Note apos around strings - they are important)

    Also if you want to select all ancestor nodes up to the root from the current one you will need (if you use a new umbraco schema, as I suppose):

    <xsl:variable name="nodes" select="$currentPage/ancestor-or-self::node()"/>

    (i.e. node() not just node). Or even simpler just:

    <xsl:variable name="nodes" select="$currentPage/ancestor-or-self::*"/>

    And yet another -  "N" is supposed to be a desirable group size. So that in you case (5 items in a group) you will need:

    <xsl:variable name="N" select="5"/>

    Happy XSLT coding :-)

Please Sign in or register to post replies

Write your reply to:

Draft