Copied to clipboard

Flag this post as spam?

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


  • Tom Cowling 144 posts 343 karma points
    Jan 06, 2015 @ 17:45
    Tom Cowling
    0

    XSLT upgrade went a bit wrong

    Hi everyone,

    I recently upgraded an old umbraco install from an early version of 4 to the latest 4.11. I had to convert the xslt to the new format and as part of that upgrade, something has gone a bit pear shaped.

    The XSLT runs through the site structure looking for nodes with a tick in the showinnav at the level it is currently at in the structure. When you click on a page in the menu, it looks at that level and checks whether or not it should add in an extra layer or not.

    It currently works fine for the top level, just doesn't display any levels below that if I click on an item that has child nodes.

    My old 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" xmlns:Exslt.ExsltCommon="urn:Exslt.ExsltCommon" xmlns:Exslt.ExsltDatesAndTimes="urn:Exslt.ExsltDatesAndTimes" xmlns:Exslt.ExsltMath="urn:Exslt.ExsltMath" xmlns:Exslt.ExsltRegularExpressions="urn:Exslt.ExsltRegularExpressions" xmlns:Exslt.ExsltStrings="urn:Exslt.ExsltStrings" xmlns:Exslt.ExsltSets="urn:Exslt.ExsltSets"
      exclude-result-prefixes="msxml umbraco.library Exslt.ExsltCommon Exslt.ExsltDatesAndTimes Exslt.ExsltMath Exslt.ExsltRegularExpressions Exslt.ExsltStrings Exslt.ExsltSets ">

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

    <xsl:param name="currentPage"/>
    <xsl:param name="rightNode" select="$currentPage/ancestor-or-self::node [@level=2]" />

    <xsl:variable name="level1" select="2"/>
    <xsl:variable name="level2" select="3"/>
    <xsl:variable name="level3" select="4"/>

    <xsl:template match="/">
    <div id="menuhead">

    <h1>
       <xsl:if test="$rightNode != '' ">
      <a href="{umbraco.library:NiceUrl($rightNode/@id)}">
      <xsl:value-of select="$rightNode/@nodeName"/>
      </a>
       </xsl:if>
    </h1>
    </div>
    <div id="leftmenu">
    <!-- The fun starts here -->
    <ul>
    <xsl:for-each select="$currentPage/ancestor-or-self::node [@level=$level1]/node [string(data [@alias='showinnav']) != '0']">
        <li>
                    <xsl:if test="$currentPage/@id = current()/@id">
                      <xsl:attribute name="class">selected</xsl:attribute>
                </xsl:if>
      <a href="{umbraco.library:NiceUrl(@id)}/">
      <xsl:value-of select="data[@alias='heading']" />
        </a>

        </li>
          <xsl:if test="$currentPage/ancestor-or-self::node/@id = current()/@id">
          <xsl:for-each select="$currentPage/ancestor-or-self::node [@level=$level2]/node [string(data [@alias='showinnav']) != '0']">              
        <li>
                          <xsl:if test="$currentPage/@id = current()/@id">
                      <xsl:attribute name="class">selected</xsl:attribute>
                </xsl:if>
                           <a href="{umbraco.library:NiceUrl(@id)}/"  class="level2">
                           <xsl:value-of select="data[@alias='heading']"/>
                           </a>
                      </li>
               <xsl:if test="$currentPage/ancestor-or-self::node/@id = current()/@id">
                  <xsl:for-each select="$currentPage/ancestor-or-self::node [@level=$level3]/node [string(data [@alias='showinnav']) != '0']">              
           <li>
                    <xsl:if test="$currentPage/@id = current()/@id">
                      <xsl:attribute name="class">selected</xsl:attribute>
                </xsl:if>
                            <a href="{umbraco.library:NiceUrl(@id)}/"  class="level3" >
                            <xsl:value-of select="data[@alias='heading']"/>
                            </a>
                          </li>
                   </xsl:for-each> 
                       </xsl:if>
          </xsl:for-each> 
          </xsl:if>
    </xsl:for-each>
    </ul>
    </div>
    </xsl:template>
    </xsl:stylesheet>

    My new 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" xmlns:Exslt.ExsltCommon="urn:Exslt.ExsltCommon" xmlns:Exslt.ExsltDatesAndTimes="urn:Exslt.ExsltDatesAndTimes" xmlns:Exslt.ExsltMath="urn:Exslt.ExsltMath" xmlns:Exslt.ExsltRegularExpressions="urn:Exslt.ExsltRegularExpressions" xmlns:Exslt.ExsltStrings="urn:Exslt.ExsltStrings" xmlns:Exslt.ExsltSets="urn:Exslt.ExsltSets"
    exclude-result-prefixes="msxml umbraco.library Exslt.ExsltCommon Exslt.ExsltDatesAndTimes Exslt.ExsltMath Exslt.ExsltRegularExpressions Exslt.ExsltStrings Exslt.ExsltSets ">

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

    <xsl:param name="currentPage"/>
    <xsl:param name="rightNode" select="$currentPage/ancestor-or-self::* [@isDoc][@level=2]" />

    <xsl:variable name="level1" select="2"/>
    <xsl:variable name="level2" select="3"/>
    <xsl:variable name="level3" select="4"/>

    <xsl:template match="/">
    <div id="menuhead">

    <h1>
    <xsl:if test="$rightNode != '' ">
    <a href="{umbraco.library:NiceUrl($rightNode/@id)}">
    <xsl:value-of select="$rightNode/@nodeName"/>
    </a>
    </xsl:if>
    </h1>
    </div>
    <div id="leftmenu">
    <!-- The fun starts here -->
    <ul>
    <xsl:for-each select="$currentPage/ancestor-or-self::* [@isDoc][@level=$level1]/* [@isDoc][string(showinnav) != '0']">
    <li>
    <xsl:if test="$currentPage/@id = current()/@id">
    <xsl:attribute name="class">selected</xsl:attribute>
    </xsl:if>
    <a href="{umbraco.library:NiceUrl(@id)}/">
    <xsl:value-of select="heading" />
    </a>
    </li>
    <xsl:if test="$currentPage/ancestor-or-self::node/@id = current()/@id">
    <xsl:for-each select="$currentPage/ancestor-or-self::*[@isDoc][@level=$level2][showinnav = 1]">
    <li>
    <xsl:if test="$currentPage/@id = current()/@id">
    <xsl:attribute name="class">selected</xsl:attribute>
    </xsl:if>
    <a href="{umbraco.library:NiceUrl(@id)}/" class="level2">
    <xsl:value-of select="heading"/>
    </a>
    </li>
    <xsl:if test="$currentPage/ancestor-or-self::node/@id = current()/@id">
    <xsl:for-each select="$currentPage/ancestor-or-self::* [@isDoc][@level=$level3]/* [@isDoc][string(showinnav) != '0']">
    <li>
    <xsl:if test="$currentPage/@id = current()/@id">
    <xsl:attribute name="class">selected</xsl:attribute>
    </xsl:if>
    <a href="{umbraco.library:NiceUrl(@id)}/" class="level3" >
    <xsl:value-of select="heading"/>
    </a>
    </li>
    </xsl:for-each>
    </xsl:if>
    </xsl:for-each>
    </xsl:if>
    </xsl:for-each>
    </ul>
    </div>
    </xsl:template>
    </xsl:stylesheet>

    I have isolated the issue to the if tests that is run (highlighted in the code). I think the syntax is slightly out there.

    If anyone could help, it'd be much appreciated as I've made the site live now and it's getting harder to revert back by the hour!!

     

    Thanks,

    Tom

  • Dennis Aaen 4500 posts 18255 karma points admin hq c-trib
    Jan 06, 2015 @ 17:58
    Dennis Aaen
    0

    Hi Tom,

    I think if you change this line

    <xsl:if test="$currentPage/ancestor-or-self::node/@id = current()/@id">

    To simply this then you should be good.

    <xsl:if test="$currentPage/ancestor-or-self/@id = current()/@id">

    Hope this helps,

    /Dennis

  • Tom Cowling 144 posts 343 karma points
    Jan 06, 2015 @ 18:02
    Tom Cowling
    0

    Thanks for the quick response Dennis.

    Didn't make any difference at all. Looking at the code, that hadn't changed so I think I may have been pointing you in the wrong direction. Could it be the syntax of the for-each?

    <xsl:for-each select="$currentPage/ancestor-or-self::node [@level=$level2]/node [string(data [@alias='showinnav']) != '0']">  
    <xsl:for-each select="$currentPage/ancestor-or-self::*[@isDoc][@level=$level2][showinnav = 1]">


    I'm not really sure though..

     

  • Tom Cowling 144 posts 343 karma points
    Jan 06, 2015 @ 18:06
    Tom Cowling
    1

    Got it!

    Should have been:

    <xsl:if test="$currentPage/ancestor-or-self::*[@id = current()/@id]">


    Thanks a lot for the help Dennis


    Panic over. :D

  • Dennis Aaen 4500 posts 18255 karma points admin hq c-trib
    Jan 06, 2015 @ 18:13
    Dennis Aaen
    0

    Hi Tom,

    If you see the prototype navigation XSLT this is how they are doing it where the umbracoNaviHide is a built in function to decide if the page should be visible in the navigation http://our.umbraco.org/wiki/reference/umbraco-best-practices/umbraconavihide

    <xsl:variable name="level" select="2"/>

    <xsl:for-each select="$currentPage/ancestor-or-self::* [@isDoc and @level=$level]/* [@isDoc and string(umbracoNaviHide) != '1']">

    And if it checked then the navigation whould not show in the navigation but you just changed this.

    Hope this helps,

    /Dennis

Please Sign in or register to post replies

Write your reply to:

Draft