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! ;-)
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!
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!
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 " "> ]>
<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 <= $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 <= $maxLevelForNav]) > 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!
Dan,
1. Add an extra parameter in your template call and check the value of that variable
2. Add a check on the list element
May need some tweaks (as i'm writing this down from top of my head..)
Hope this helps.
Regards,
/Dirk
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
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
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.
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
is working on a reply...