Copied to clipboard

Flag this post as spam?

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


  • Tim Officer 18 posts 39 karma points
    Nov 09, 2011 @ 22:06
    Tim Officer
    0

    no nodes leaves empty <ul>

    I tried searching the forums and I found similar posts but nothing that worked exactly.

    When I have no nodes in my XSLT I get a ul tag like this:

    <div id="leftNavHolder">

    <ul class="leftNav" />

    </div>

    I added a test to make sure there are child nodes on the current node before showing the list but I am still getting the empty ul tag.....any ideas?

    heres the short version of my code:

        <xsl:if test="count($currentPage/ancestor-or-self::*) &gt; 1">
          <ul class="leftNav">
          <xsl:for-each select="$currentPage/ancestor-or-self::* [@level=$L3]/* [@isDoc and string(sideNavShow) = '1']">

            <li></li>

    </xsl:for-each>

  • Tim Officer 18 posts 39 karma points
    Nov 09, 2011 @ 22:10
    Tim Officer
    0

        <xsl:if test="count($currentPage/ancestor-or-self::*) &gt; 1">
          <ul class="leftNav">
          <xsl:for-each select="$currentPage/ancestor-or-self::* [@level=$L3]/* [@isDoc and string(sideNavShow) = '1']">
            <li>
            </li>
          </xsl:for-each>
        </ul>
        </xsl:if>

     

    I thought it should check to make sure the count of child nodes is greater than 1.

    How do I test that there are child nodes before spitting out the UL?

  • Tim Officer 18 posts 39 karma points
    Nov 09, 2011 @ 22:11
    Tim Officer
    0

    whooops, that first post got screwed up, look at the second post for the xslt

  • Jan Skovgaard 11280 posts 23678 karma points MVP 11x admin c-trib
    Nov 09, 2011 @ 22:12
    Jan Skovgaard
    0

    Hi Tim

    You should probably make sure that it's a document you're dealing with.

    Make your count like this count($currentPage/ancestor-or-self::*[@isDoc] &gt; 0).

    /Jan

  • Jan Skovgaard 11280 posts 23678 karma points MVP 11x admin c-trib
    Nov 09, 2011 @ 22:14
    Jan Skovgaard
    0

    Just saw your second post...

    Could you please post the entire code? I have a feeling this could might be solved in a much better way but would like to see all you got first to make sure I get it all right.

    /Jan

  • Chriztian Steinmeier 2798 posts 8788 karma points MVP 8x admin c-trib
    Nov 09, 2011 @ 22:27
    Chriztian Steinmeier
    0

    Hi Tim,

    You need to perform the same selection in the test, as you're using in the for-each - right now, your initial test checks if $currentPage has more than one parent node (including itself), which is true for all pages in the site, save for the root node. So copy the select expression from the for-each and use it in the test, which should work.

    (You don't need to wrap the count() method around it - the test will return false if there are no nodes to select)  

    /Chriztian

     

  • Tim Officer 18 posts 39 karma points
    Nov 09, 2011 @ 22:37
    Tim Officer
    0

    thank you Chriztian, that worked perfectly!

    here is my final code for anyone with a similar issue.

     

     <xsl:param name="currentPage"/>

      <!-- Input the documenttype you want here -->
      <xsl:variable name="L3" select="2"/>
      <xsl:variable name="L4" select="3"/>
      <xsl:variable name="TotalNodes" select="count(*)"/>
      <xsl:template match="/">

        <!-- The fun starts here -->
        <!--l3 navigation-->
          <xsl:if test="$currentPage/ancestor-or-self::* [@level=$L3]/* [@isDoc and string(sideNavShow) = '1']">
          <ul class="leftNav">
          <xsl:for-each select="$currentPage/ancestor-or-self::* [@level=$L3]/* [@isDoc and string(sideNavShow) = '1']">
            <li>
              <xsl:if test="$currentPage/ancestor-or-self::* [@level]/@id = current()/@id">
                <xsl:attribute name="class">
                  <xsl:text>active</xsl:text>
                </xsl:attribute>
              </xsl:if>
                <a href="{umbraco.library:NiceUrl(@id)}">
                  <xsl:value-of select="@nodeName"/>
                </a>
              <!--l4 navigation-->
              <xsl:if test="count(./* [@isDoc and string(sideNavShow) = '1']) &gt; 0">
                <ul class="leftSubNav">
                  <xsl:for-each select="./* [@isDoc and string(sideNavShow) = '1']">
                    <li>
                      <xsl:if test="$currentPage/ancestor-or-self::* [@level]/@id = current()/@id">
                        <xsl:attribute name="class">
                          <xsl:text>active_child</xsl:text>
                        </xsl:attribute>
                      </xsl:if>
                      <a href="{umbraco.library:NiceUrl(@id)}">
                        <xsl:value-of select="@nodeName"/>
                      </a>
                      <!--l5 navigation-->
                      <xsl:if test="count(./* [@isDoc and string(sideNavShow) = '1']) &gt; 0">
                        <ul class="leftSubSubNav">
                          <xsl:for-each select="./* [@isDoc and string(sideNavShow) = '1']">
                            <li>
                              <xsl:if test="$currentPage/ancestor-or-self::* [@level]/@id = current()/@id">
                                <xsl:attribute name="class">
                                  <xsl:text>active_child</xsl:text>
                                </xsl:attribute>
                              </xsl:if>
                              <a href="{umbraco.library:NiceUrl(@id)}">
                                <xsl:value-of select="@nodeName"/>
                              </a>
                            </li>
                          </xsl:for-each>
                        </ul>
                      </xsl:if>
                      <!-- end l5 -->
                    </li>
                  </xsl:for-each>
                </ul>
              </xsl:if>
              <!-- end l4 -->
            </li>
          </xsl:for-each>
        </ul>
          </xsl:if>
      </xsl:template>

  • Chriztian Steinmeier 2798 posts 8788 karma points MVP 8x admin c-trib
    Nov 10, 2011 @ 09:19
    Chriztian Steinmeier
    1

    Hi Tim,

    I can recommend taking a look at the apply-templates approach to doing XSLT - for navigations, sitemaps etc. it's so much easier to manage. Here's a rewrite of your XSLT for comparison:

    <xsl:param name="currentPage" />
    
    <!-- Customization -->
    <xsl:variable name="startLevel" select="2" />
    <xsl:variable name="lastLevel" select="4" />
    
    <!-- Grab the root of the navigation -->
    <xsl:variable name="navRoot" select="$currentPage/ancestor-or-self::*[@level = $startLevel]" />
    
    <xsl:template match="/">
        <ul class="leftNav">
            <xsl:apply-templates select="$navRoot/*[@isDoc][sideNavShow = 1]" />
        </ul>
    </xsl:template>
    
    <!-- Same template for all items in nav -->
    <xsl:template match="*[@isDoc]">
        <li>
            <!-- If currentPage is somewhere below add an active(_child) class -->
            <xsl:if test="descendant-or-self::*[@id = $currentPage/@id]">
                <xsl:attribute name="class">
                    <xsl:text>active</xsl:text>
                    <xsl:if test="@level &gt; $startLevel">_child</xsl:if>
                </xsl:attribute>
            </xsl:if>
            <a href="{umbraco.library:NiceUrl(@id)}">
                <xsl:value-of select="@nodeName"/>
            </a>
            <!-- Continue processing children until (and including) $lastLevel -->
            <xsl:if test="*[@isDoc][@level &lt;= $lastLevel][sideNavShow = 1]">
                <ul class="leftSubNav">
                    <xsl:attribute name="class">
                        <xsl:text>leftSub</xsl:text>
                        <xsl:if test="@level = $lastLevel">Sub</xsl:if>
                        <xsl:text>Nav</xsl:text>
                    </xsl:attribute>
                    <xsl:apply-templates select="*[@isDoc][sideNavShow = 1]" />
                </ul>
            </xsl:if>
        </li>
    </xsl:template>

    One thing that would make it even better would be to handle the multiple levels generically in CSS instead of adding different class names ('active' vs. 'active_child'  and 'leftSubNav' vs. 'leftSubSubnav') on every level (but that's probably a little out of scope for this).

    /Chriztian

  • Tim Officer 18 posts 39 karma points
    Nov 10, 2011 @ 16:37
    Tim Officer
    0

    Thanks Chriztian,

    I am still pretty new to Umbraco (about 4 months in) and haven't yet gotten around to really learning XSLT. Thus far I've just been copy and pasting and poking around in the dark until I get something sort of right. I really need to learn it though, so this will definetly help get me started. This way of doing things looks much cleaner and easier to mantain. If you've got any tips for learning XSLT please share. I'm going to start with the OurUmbraco XSLT section.

    thanks again :)

     

Please Sign in or register to post replies

Write your reply to:

Draft