Copied to clipboard

Flag this post as spam?

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


  • Max Mumford 266 posts 293 karma points
    Jul 11, 2011 @ 18:31
    Max Mumford
    0

    Use if statement to exclude all nodes of certain level and node type

    Hi all,

    I'm having some problems with a (relatively) complicated xslt statement.

    I want to exclude a set of nodes from my navigation menu based on the following properties:

    • level = 4
    • name() != 'uBlogsyPost'
    • OR
    • name() != 'umbracoBlogPost'

    so I want to exclude all items with a level of 4, with either the doctype of uBlogsyPost or umbracoBlogPost.

    I would do it with a document property but I want it to be automatic as opposed to manual.

    Here is my current xslt:

      <xsl:if test="($node/umbracoNaviHide != '1') and (@level != 4 and (name() != 'uBlogsyPost' or name() != 'umbracoBlogPost'))">

    This line is placed within a template that get's called in a loop that loops through every node in the site, then within the above if statement is code that outputs the menu itself.

    With the above statement it stops as soon as it starts and does not output any code.

    Thanks,

    Max.

  • Jan Skovgaard 11280 posts 23678 karma points MVP 11x admin c-trib
    Jul 11, 2011 @ 18:33
    Jan Skovgaard
    0

    Hi Max

    Could you perhaps post the whole XSLT snippet? I have an idea that what you're trying to do could be handled in a much better way using an apply-template actually. But would like to see more of the code.

    /Jan

  • Max Mumford 266 posts 293 karma points
    Jul 11, 2011 @ 18:39
    Max Mumford
    0

    Sure, here is the xslt for the nav before I started messing around with it trying to achieve the above: 

    <?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">
        <table cellspacing="0">
          <tr>
            <td id="navleft"></td>
            <td id="navcentre">
              <ul>
                <li>
                  <!-- output home page node then run through template for all other top level nodes -->
                  <xsl:if test="$currentPage/@nodeName = 'Home'">
                    <xsl:attribute name="class">current</xsl:attribute>
                  </xsl:if>
                  <href="/">Home</a></li></ul>
                  <xsl:call-template name="printListe">
                    <xsl:with-param name="node" select="$currentPage/ancestor-or-self::* [@isDoc and @level = 1]"/>  
                    <xsl:with-param name="id" select="string('treemenu1')"/>  
                  </xsl:call-template>
            </td>
            <td id="navright"></td>
          </tr>
        </table>
      </div>
      
    </xsl:template>

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

      <xsl:if test="($node/umbracoNaviHide != '1')">
        <xsl:if test="count($node/* [@isDoc and umbracoNaviHide != 1]) &gt; 0">
          <ul>
            <xsl:if test="$id != ''">
              <xsl:attribute name="id"><xsl:value-of select="$id"/></xsl:attribute>
            </xsl:if>
            <xsl:for-each select="$node/* [@isDoc and umbracoNaviHide != 1]">
              
                  <xsl:call-template name="buildLi">
                    <xsl:with-param name="node" select="." />
                    <xsl:with-param name="href" select="umbraco.library:NiceUrl(@id)" />
                    <xsl:with-param name="text" select="@nodeName" />
                  </xsl:call-template>
                
            </xsl:for-each>
          </ul>
        </xsl:if>
      </xsl:if>
    </xsl:template>

        
    <!-- nav list item builder template, used above -->
    <xsl:template name="buildLi">
      <xsl:param name="node" />
      <xsl:param name="href" />
      <xsl:param name="text" />
      
          <li>
            <a>
              <xsl:attribute name="href">
                <xsl:value-of select="$href" />
              </xsl:attribute>
              <xsl:if test="string-length($text) &gt; 25">
                <xsl:attribute name="title">
                  <xsl:value-of select="$text" />
                </xsl:attribute>
              </xsl:if>
              
              <!-- if text needs shrinking, add full length version in title -->
              <xsl:choose>
                <xsl:when test="string-length(@nodeName) &gt; 25">
                  <xsl:value-of select="concat((substring($text,0,24)),'...')" />
                </xsl:when>
                <xsl:otherwise>
                  <xsl:value-of select="$text" />
                </xsl:otherwise>
              </xsl:choose
            </a>
            
            <!-- shrink text if need be -->
            <xsl:if test="count($node/*[@isDoc and umbracoNaviHide != 1]) &gt; 0">
              <xsl:call-template name="printListe">
                <xsl:with-param name="node" select="."/>
              </xsl:call-template>
            </xsl:if>
          </li>
        
    </xsl:template>
       
    </xsl:stylesheet>

  • Chriztian Steinmeier 2798 posts 8788 karma points MVP 8x admin c-trib
    Jul 12, 2011 @ 02:40
    Chriztian Steinmeier
    0

    Hi Max,

    As Jan implied, this sort of thing is actually better handled using match templates and the apply-templates instruction; One way of doing that looks like this:

    <?xml version="1.0" encoding="utf-8" ?>
    <!DOCTYPE xsl:stylesheet [
        <!ENTITY nbsp "&#x0A;">
    ]>
    <xsl:stylesheet
        version="1.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:umb="urn:umbraco.library"
        exclude-result-prefixes="umb"
    >
    
        <xsl:output method="xml" indent="yes" omit-xml-declaration="yes" />
    
        <xsl:param name="currentPage" />
        <xsl:variable name="level" select="1" />
    
        <xsl:variable name="navRoot" select="$currentPage/ancestor-or-self::*[@level = $level][not(umbracoNaviHide = 1)]" />
        <xsl:variable name="navRootItems" select="$navRoot/*[@isDoc][not(umbracoNaviHide = 1)]" />
    
        <xsl:template match="/">
            <div class="navtree">
                <table cellspacing="0">
                    <tr>
                        <td id="navleft" />
                        <td id="navcentre">
                            <ul>
                                <li>
                                    <xsl:if test="$currentPage/@nodeName = 'Home'"><xsl:attribute name="class">current</xsl:attribute></xsl:if>
                                    <a href="/">Home</a>
                                </li>
                            </ul>
    
                            <xsl:if test="$navRootItems">
                                <ul id="treemenu1">
                                    <xsl:apply-templates select="$navRootItems" />
                                </ul>
                            </xsl:if>
                        </td>
                        <td id="navright" />
                    </tr>
                </table>
            </div>
        </xsl:template>
    
        <xsl:template match="*[@isDoc]">
            <li>
                <xsl:if test="@id = $currentPage/@id"><xsl:attribute name="class">current</xsl:attribute></xsl:if>
                <a href="{umb:NiceUrl(@id)}">
                    <xsl:apply-templates select="@nodeName" />
                </a>
                <xsl:if test="*[@isDoc][not(umbracoNaviHide = 1)]">
                    <ul>
                        <xsl:apply-templates select="*[@isDoc][not(umbracoNaviHide = 1)][not((self::uBlogsyPost | self::umbracoBlogPost)[@level = 4])]" />
                    </ul>
                </xsl:if>
            </li>
        </xsl:template>
    
        <xsl:template match="@nodeName[string-length() &gt; 25]">
            <xsl:attribute name="title">
                <xsl:value-of select="." />
            </xsl:attribute>
            <xsl:value-of select="concat(substring(., 1, 24), '&#8230;')" />
        </xsl:template>
    
    </xsl:stylesheet>
    
    You'll likely have some questions, so feel free to ask!
     

    /Chriztian

  • Max Mumford 266 posts 293 karma points
    Jul 12, 2011 @ 12:50
    Max Mumford
    0

    Great! That did it. Only problem was that the <ul> tags were still being rendered inside the

     

            <xsl:templatematch="*[@isDoc]">

     

    template which, in ie6 (surprise surprise) messed up the menu. I changed the code slightly to this:

    <?xml version="1.0" encoding="utf-8" ?>
    <!DOCTYPE xsl:stylesheet [
            <!ENTITY nbsp "&#x0A;">
    ]>
    <xsl:stylesheet
            version="1.0"
            xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
            xmlns:umb="urn:umbraco.library"
            exclude-result-prefixes="umb"
    >

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

            <xsl:param name="currentPage" />
            <xsl:variable name="level" select="1" />
            
            <xsl:variable name="navRoot" select="$currentPage/ancestor-or-self::*[@level = $level][not(umbracoNaviHide = 1)]" />
            <xsl:variable name="navRootItems" select="$navRoot/*[@isDoc][not(umbracoNaviHide = 1)]" />

            <xsl:template match="/">
              <div class="navtree">
                <table cellspacing="0">
                  <tr>
                    <td id="navleft" />
                    <td id="navcentre">
                      <ul>
                        <li>
                          <xsl:if test="$currentPage/@nodeName = 'Home'"><xsl:attribute name="class">current</xsl:attribute></xsl:if>
                          <href="/">Home</a>
                        </li>
                      </ul>

                      <xsl:if test="$navRootItems">
                        <ul id="treemenu1">
                          <xsl:apply-templates select="$navRootItems" />
                        </ul>
                      </xsl:if>
                    </td>
                    <td id="navright" />
                  </tr>
                </table>
              </div>
            </xsl:template>

            <xsl:template match="*[@isDoc]">
              <li>
                <xsl:if test="@id = $currentPage/@id"><xsl:attribute name="class">current</xsl:attribute></xsl:if>
                <href="{umb:NiceUrl(@id)}">
                  <xsl:apply-templates select="@nodeName" />
                </a>
                <xsl:if test="*[@isDoc][not(umbracoNaviHide = 1)][not((self::uBlogsyFolderMonth | self::umbracoBlogDateFolder)[@level = 5])]">
                  <ul>
                    <xsl:apply-templates select="*[@isDoc][not(umbracoNaviHide = 1)][not((self::uBlogsyFolderMonth | self::umbracoBlogDateFolder)[@level = 5])]" />
                  </ul>
                </xsl:if>
              </li>
            </xsl:template>
            
            <xsl:template match="@nodeName[string-length() &gt; 25]">
              <xsl:attribute name="title">
                <xsl:value-of select="." />
              </xsl:attribute>
              <xsl:value-of select="concat(substring(., 1, 24), '&#8230;')" />
            </xsl:template>
            
    </xsl:stylesheet>

    Which seems to have fixed it.

    From the above I understand that apply-templates tries to match a string or nodeset against all possible templates, either by properties, attributes or names.

    The only question I have, is how does the below template call

    <xsl:template match="@nodeName[string-length() &gt; 25]">

    Know to simply render the non-truncated version of @nodeName if it is less than 25 characters long?

    Thanks for your help, I have learnt a lot!!
    Max.

Please Sign in or register to post replies

Write your reply to:

Draft