<xsl:for-each select="$currentPage/ancestor-or-self::* [@level=$level]/* [@isDoc and string(umbracoNaviHide) != '1']">
<!-- Check if link should be active --> <xsl:choose> <xsl:when test="$currentPage/@id = @id"> <li class="active"> <a href="{umbraco.library:NiceUrl(@id)}"> <xsl:value-of select="@nodeName"/> </a> </li> </xsl:when> <xsl:otherwise> <li> <a href="{umbraco.library:NiceUrl(@id)}"> <xsl:value-of select="@nodeName"/> </a> </li> </xsl:otherwise> </xsl:choose>
</xsl:for-each>
Level was set to 2, so when browsing a section, the navigation would display all its children. But, now i want to have a section within a section like so..
Home
Section 1
Page 1
Page 2
Section1.1
Page 1.1
Section 2
Page 1
Page 2
Section 3
Page 1
Page 2
And the navigation is thrown off, when i click section 1.1 the navigation shows its siblings, instead i want it to show its children, but if i make this change, im still shown its siblings, if i correct it to level 3, im shown its children, but i cant link to its siblings.
Im just wondering what the best approach is for this
I'm working on something like this just now, which will write out all the sub-navigation regardless of where the user currently is. I've added a few comments to the code that should help
<!-- update this variable on how deep your site map should be --> <xsl:variable name="maxLevelForSitemap" select="6"/>
<xsl:template match="/"> <!-- Always start the side navigation at level 2 --> <xsl:variable name="parentNode" select="$currentPage/ancestor-or-self::* [@isDoc and @level=2]" /> <!-- only call the template if the parent node is present and has children --> <xsl:if test="string($parentNode/@id) != '' and count($parentNode/* [@isDoc and string(./umbracoNaviHide) != '1']) > 0"> <xsl:call-template name="drawNodes"> <xsl:with-param name="parent" select="$parentNode"/> </xsl:call-template> </xsl:if> </xsl:template>
<xsl:template name="drawNodes"> <xsl:param name="parent"/> <!-- check to see if this page isn't hidden, or if it is hidden that the user is logged on --> <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 class="subnav"> <!-- for each child page that isn't hidden or one of our node types that we don't to show --> <xsl:for-each select="$parent/* [@isDoc and string(./umbracoNaviHide) != '1' and @level <= $maxLevelForSitemap and name()!='NewsItem' and name()!='Event' and name()!='DateFolder']"> <li> <!-- Check if this is on the current path --> <xsl:if test="$currentPage/ancestor-or-self::*/@id = current()/@id"> <xsl:attribute name="class">current</xsl:attribute> </xsl:if> <a href="{umbraco.library:NiceUrl(@id)}"> <xsl:value-of select="@nodeName"/></a> <!-- If this page has children, call the template recursively to continue writing out the navigation --> <xsl:if test=" count(./* [@isDoc and string(./umbracoNaviHide) != '1' and @level <= $maxLevelForSitemap and name()!='NewsItem' and name()!='Event' and name()!='DateFolder']) > 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>
With this xslt, the navigation for section1, shows links to page 1, page 2 and section 1.1 which is good, but it also shows the link to page1.1 which should only be visible from the section 1.1 navigation (if this makes sense). If the node is a "Section" i want to display its children, if it is a "Page" i want to display its siblings. Is this possible?
Hi, yeah i dont want to show the link to section 2 or section 3 from section 1. Ill describe it as best i can...
From home, the navigation should consist of "Section 1, Section 2, Section3". On clicking one of these links, the user decends into the section. Once in a section, the navigation changes to display children of that section. So, assuming the user navigates to section 1, the navigation would be "Page 1, Page 2, Section 1.1". Now, if the user is viewing a page, the navigation doesnt need to change, or rather, it should display the pages siblings. So, if the user views page 1, the navigation would still be "Page 1(active link), Page 2, Section 1.1". If the user navigates to section 1.1, the navigation should change and show the children of this section, this should be "Page 1.1"
Sorry for being a bit slow here! I'm still not 100% sure of the requirement, but I think you might be able to get this by changing the parentNode variable depending on where you are in the tree, so if you're at a level 3 page start the subnav at level 3 etc instead of level 2.
Yeah just noticed it should be a ":" still no luck tho, i dont get any menu rendered then,
I thought that the $parentNode variable actually contains a set, because its gets the current nodes ancestors and itself, which is why it makes sense that i get the following error.. how do i select the first from this set? is that even the right one?
"To use a result tree fragment in a path expression, first convert it to a node-set using the msxsl:node-set() function. "
Im still having trouble. As far as i am aware, the $parentNode should now contain the node for which children to get, so i try and loop through them. However, i still get no menu selected. I know $parentNode is set, as if i just use that in the for each, it renders a link to itself. Yet for some reason, if i try and access its children, i get no menu displayed.
Below is the code im using.
I get the parent ndoe, then loop through its children and render a list, theres a little choose statement in there just to determin whether to highlight the current link.
And im getting a navigation rendered, i can look at section 1 and it will show page 1, 2, 3 and section 1.1, i can choose section 1.1 and it will show me page 1.1. However, if i am in section 1 and choose page 1, 2, or 3, the navigation just dissapears. (Also, i know hard coding levels 2, and 3 like above wont cope well with expansion, its just a test for now.
Im nto entirely sure why decrementing the level if the page is not a section works, as i originally thought incrementing it if it was a section, and keepign it the same if it was a page would work, so this took some trial and error. If anyone has a better method, or could even shed a little light on how this actually worked then i would be greatful! :)
Navigation Help
Hi There,
I had a sitemap as follows.
<xsl:for-each select="$currentPage/ancestor-or-self::* [@level=$level]/* [@isDoc and string(umbracoNaviHide) != '1']">
<!-- Check if link should be active -->
<xsl:choose>
<xsl:when test="$currentPage/@id = @id">
<li class="active">
<a href="{umbraco.library:NiceUrl(@id)}">
<xsl:value-of select="@nodeName"/>
</a>
</li>
</xsl:when>
<xsl:otherwise>
<li>
<a href="{umbraco.library:NiceUrl(@id)}">
<xsl:value-of select="@nodeName"/>
</a>
</li>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
Hi Tc
I'm working on something like this just now, which will write out all the sub-navigation regardless of where the user currently is. I've added a few comments to the code that should help
Dan
Hey, thanks for the speedy reply!
I havent had chance to test this but will update you when i do.
Will this be able to cope with displaying children if it is a "section" or displaying its ancestors if it is a "page" similar to my site map above?
I should get chance to test it soon.
Thanks again!
Just got round to testing.
With this xslt, the navigation for section1, shows links to page 1, page 2 and section 1.1 which is good, but it also shows the link to page1.1 which should only be visible from the section 1.1 navigation (if this makes sense). If the node is a "Section" i want to display its children, if it is a "Page" i want to display its siblings. Is this possible?
Thanks again!
Could this be solved with CSS?
Or do you not want to show the link to section 2, section 3 etc if you're inside section 1?
Dan
Hi, yeah i dont want to show the link to section 2 or section 3 from section 1. Ill describe it as best i can...
From home, the navigation should consist of "Section 1, Section 2, Section3".
On clicking one of these links, the user decends into the section. Once in a section, the navigation changes to display children of that section. So, assuming the user navigates to section 1, the navigation would be "Page 1, Page 2, Section 1.1". Now, if the user is viewing a page, the navigation doesnt need to change, or rather, it should display the pages siblings. So, if the user views page 1, the navigation would still be "Page 1(active link), Page 2, Section 1.1". If the user navigates to section 1.1, the navigation should change and show the children of this section, this should be "Page 1.1"
Thanks again!
Sorry for being a bit slow here! I'm still not 100% sure of the requirement, but I think you might be able to get this by changing the parentNode variable depending on where you are in the tree, so if you're at a level 3 page start the subnav at level 3 etc instead of level 2.
Something along these lines/
Note - the above code might not do what you need, but perhaps by playing with setting the initial parent node you can get the outcome you're after.
Dan
Hi again,
Im still not having much luck with this, how do i go about using that piece of code you put? I thought i could just use
but for some reason its not letting me do that and gives an error asking me to convert to node-set();
You would have to use this code
Rich
Hi Rich, i used the code you put above and got the gfollowing error
umbraco.library.GetXmlNodeById()' is an unknown XSLT function
Sorry, typo. Try this:
Rich
Yeah just noticed it should be a ":"
still no luck tho, i dont get any menu rendered then,
I thought that the $parentNode variable actually contains a set, because its gets the current nodes ancestors and itself, which is why it makes sense that i get the following error.. how do i select the first from this set? is that even the right one?
"To use a result tree fragment in a path expression, first convert it to a node-set using the msxsl:node-set() function. "
Hi tc
To use GetXmlNodeById we need to save an integer id instead of the node. So instead of
You'd use this
Then you can use
Hope this helps,
Dan
Hi Dan,
that saved properly, thanks.
Im still having trouble. As far as i am aware, the $parentNode should now contain the node for which children to get, so i try and loop through them. However, i still get no menu selected. I know $parentNode is set, as if i just use that in the for each, it renders a link to itself. Yet for some reason, if i try and access its children, i get no menu displayed.
Below is the code im using.
I get the parent ndoe, then loop through its children and render a list, theres a little choose statement in there just to determin whether to highlight the current link.
<xsl:variable name="parentNode">
<xsl:choose>
<xsl:when test="$currentPage/@level < 3">
<xsl:value-of select="$currentPage/ancestor-or-self::* [@isDoc and @level=2]/@id" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$currentPage/ancestor-or-self::* [@isDoc and @level=3]/@id" />
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:template match="/">
<!-- The fun starts here -->
<xsl:if test="$parentNode > 0" >
<xsl:for-each select="umbraco.library:GetXmlNodeById($parentNode)/*">
<!-- Check if link should be active -->
<xsl:choose>
<xsl:when test="$currentPage/@id = @id">
<li class="active">
<a href="{umbraco.library:NiceUrl(@id)}">
<xsl:value-of select="@nodeName"/>
</a>
</li>
</xsl:when>
<xsl:otherwise>
<li>
<a href="{umbraco.library:NiceUrl(@id)}">
<xsl:value-of select="@nodeName"/>
</a>
</li>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:if>
</xsl:template>
OKay, im makign progress here
i used the following code to set the level variable
<xsl:variable name="level">
<xsl:choose>
<xsl:when test="$currentPage/@level < 3">
<xsl:text>2</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>3</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
And im getting a navigation rendered, i can look at section 1 and it will show page 1, 2, 3 and section 1.1, i can choose section 1.1 and it will show me page 1.1. However, if i am in section 1 and choose page 1, 2, or 3, the navigation just dissapears. (Also, i know hard coding levels 2, and 3 like above wont cope well with expansion, its just a test for now.
Thanks
Okay, i seem to have got somewhere,
What i did was decrement the level if this page is not a section.
<xsl:variable name="level">
<xsl:choose>
<xsl:when test="$currentPage/@nodeName = 'Home'">
<xsl:text>0</xsl:text>
</xsl:when>
<xsl:when test="$currentPage/@nodeType = 1135">
<xsl:value-of select="$currentPage/@level" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$currentPage/@level - 1" />
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
Im nto entirely sure why decrementing the level if the page is not a section works, as i originally thought incrementing it if it was a section, and keepign it the same if it was a page would work, so this took some trial and error. If anyone has a better method, or could even shed a little light on how this actually worked then i would be greatful! :)
Thanks!
is working on a reply...