Copied to clipboard

Flag this post as spam?

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


  • Dan 1288 posts 3921 karma points c-trib
    Sep 18, 2009 @ 10:53
    Dan
    0

    Set id and class on first ul in nested list

    Hi,

    I've modified the sitemap XSLT file to use for my navigation (which is a two-level nested list).  The code looks like this:

    <?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:variable name="maxLevelForNav" select="3"/>

    <xsl:template match="/">
    <xsl:call-template name="drawNodes"> 
    <xsl:with-param name="parent" select="$currentPage/ancestor-or-self::node [@level=1]"/> 
    </xsl:call-template>
    </xsl:template>

    <xsl:template name="drawNodes">
    <xsl:param name="parent"/>
    <xsl:if test="umbraco.library:IsProtected($parent/@id, $parent/@path) = 0 or (umbraco.library:IsProtected($parent/@id, $parent/@path) = 1 and umbraco.library:IsLoggedOn() = 1)">
    <ul><xsl:for-each select="$parent/node [string(./data [@alias='umbracoNaviHide']) != '1' and @level &lt;= $maxLevelForNav]">
    <li> 
    <a href="{umbraco.library:NiceUrl(@id)}">
    <xsl:value-of select="@nodeName"/></a> 
    <xsl:if test="count(./node [string(./data [@alias='umbracoNaviHide']) != '1' and @level &lt;= $maxLevelForNav]) &gt; 0">  
    <xsl:call-template name="drawNodes">   
    <xsl:with-param name="parent" select="."/>   
    </xsl:call-template> 
    </xsl:if>
    </li>
    </xsl:for-each>
    </ul>
    </xsl:if>
    </xsl:template>
    </xsl:stylesheet>

    I have two questions though:

    1. How do I get the first <ul> tag to have a class of 'myClass' and an id of 'myId'?

    2. How do I add a class of 'selected' to the <li> tag when I'm in that section?

     

    These are probably really basic questions, but I'm brand new to XSLT so I'm not sure of the right approach to do these things.

    Thanks y'all!

  • Dirk De Grave 4541 posts 6021 karma points MVP 3x admin c-trib
    Sep 18, 2009 @ 11:38
    Dirk De Grave
    1

    Dan,

    1. Add an extra parameter in your template call and check the value of that variable

    <xsl:template match="/">
    <xsl:call-template name="drawNodes">
    <xsl:with-param name="parent" select="$currentPage/ancestor-or-self::node [@level=1]"/>
    <xsl:with-param name="topLevel" select="1"/>
    </xsl:call-template>
    </xsl:template>...
    <xsl:call-template name="drawNodes">
    <xsl:with-param name="parent" select="."/>
    <xsl:with-param name="topLevel" select="0"/>
    </xsl:call-template>...
    <xsl:template name="drawNodes">
    <xsl:param name="parent"/>
    <xsl:param name="topLevel"/>...
    <ul>
    <xsl:if test="string($topLevel) = '1'">
    <xsl:attribute name="class"><xsl:text>myClass</xsl:text></xsl:attribute>
    <xsl:attribute name="id"><xsl:text>myId</xsl:text></xsl:attribute>
    </xsl:if>...

     

    2. Add a check on the list element

    <li>
    <xsl:if test="./ancestor-or-self::node [@id = ./@id">
    <xsl:attribute name="class"><xsl:text>selected</xsl:text></xsl:attribute>
    </xsl:if>
    <a href="{umbraco.library:NiceUrl(@id)}"><xsl:value-of select="@nodeName"/></a>

     

    May need some tweaks (as i'm writing this down from top of my head..)

     

    Hope this helps.

     

    Regards,

    /Dirk

  • Tim 225 posts 690 karma points
    Sep 18, 2009 @ 11:46
    Tim
    0

    You could also take a look at this navigation package, it contains working examples of all you want to achieve and more. So it might save you a bit of time writing all that pesky xslt! ;-)

    T

  • Dan 1288 posts 3921 karma points c-trib
    Sep 18, 2009 @ 12:39
    Dan
    0

    Thanks Tim - I tried that package but by default it didn't write out all of my navigation (I'm using 'Suckerfish' and jQuery to hide the unselected elements, so need the full navigation to be written out to HTML) so immediately I was a bit stumped.

    Thanks too Dirk.  I've implemented point 1 but when I save it errors:

    Error occured

    System.OverflowException: Value was either too large or too small for an Int32.
    at System.Convert.ToInt32(Double value)
    at System.Double.System.IConvertible.ToInt32(IFormatProvider provider)
    at System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider)
    at System.Xml.Xsl.Runtime.XmlQueryRuntime.ChangeTypeXsltArgument(XmlQueryType xmlType, Object value, Type destinationType)
    at System.Xml.Xsl.Runtime.XmlQueryContext.InvokeXsltLateBoundFunction(String name, String namespaceUri, IList`1[] args)
    at (XmlQueryRuntime {urn:schemas-microsoft-com:xslt-debug}runtime, XPathNavigator parent, IList`1 topLevel)
    at Root(XmlQueryRuntime {urn:schemas-microsoft-com:xslt-debug}runtime)
    at Execute(XmlQueryRuntime {urn:schemas-microsoft-com:xslt-debug}runtime)
    at System.Xml.Xsl.XmlILCommand.Execute(Object defaultDocument, XmlResolver dataSources, XsltArgumentList argumentList, XmlSequenceWriter results)
    at System.Xml.Xsl.XmlILCommand.Execute(Object defaultDocument, XmlResolver dataSources, XsltArgumentList argumentList, XmlWriter writer, Boolean closeWriter)
    at System.Xml.Xsl.XmlILCommand.Execute(IXPathNavigable contextDocument, XmlResolver dataSources, XsltArgumentList argumentList, XmlWriter results)
    at System.Xml.Xsl.XmlILCommand.Execute(IXPathNavigable contextDocument, XmlResolver dataSources, XsltArgumentList argumentList, TextWriter results)
    at System.Xml.Xsl.XslCompiledTransform.Transform(IXPathNavigable input, XsltArgumentList arguments, TextWriter results)
    at umbraco.presentation.webservices.codeEditorSave.SaveXslt(String fileName, String oldName, String fileContents, Boolean ignoreDebugging)

     

    Any ideas?  I suspect it's because of the "." in the line: <xsl:with-param name="parent" select="."/>, but really I have no idea!

    Thanks

  • Dan 1288 posts 3921 karma points c-trib
    Sep 18, 2009 @ 12:54
    Dan
    0

    Hmm, the second part error also.  I think this is because of a typo.  I changed it to:

    <xsl:if test="./ancestor-or-self::node [@id = ./@id]">
    <xsl:attribute name="class"><xsl:text>current</xsl:text></xsl:attribute>
    </xsl:if>

    Note: added the closing square bracket in the first line.

    However, this has just added the class to all '<li>' tags.

  • Tim 225 posts 690 karma points
    Sep 18, 2009 @ 12:59
    Tim
    0

    Hi Dan,

    No worries, keep your eyes peeled for the next version of the package (as it will be able to write the whole nav out at once, with selected and branch classes all working). I'm hoping to release it later today!

    T

     

     

Please Sign in or register to post replies

Write your reply to:

Draft