Noobie question here, i have scoured the forum trying to sort this but can't find what i need.
Umbraco 4.5.2, Windows IIS 6, ASP .NET 4.0
I have the following structure, like most people:
Home About Us Products Prod 1 Prod 2 Portfolio Port 1 Port 2
I only want to show sub levels when i'm on the products page or portfolio page. The XSLT i have seems to work ok for that but when i go to the about us page, it thinks products and portfolio are sub levels to about us.
I have only been using Umbraco a week so i'm not sure what i'm missing and hoping someone will be able to help me.
<!-- Input the documenttype you want here --> <!-- Typically '1' for topnavigtaion and '2' for 2nd level --> <!-- Use div elements around this macro combined with css --> <!-- for styling the navigation --> <xsl:variablename="level"select="1"/> <xsl:variablename="siteRoot"select="$currentPage/ancestor-or-self::*[@level = 1]"/> <xsl:templatematch="/"> <!-- The fun starts here --> <ul> <li> <ahref="{umbraco.library:NiceUrl($siteRoot/@id)}"> <xsl:value-ofselect="$currentPage/ancestor-or-self::*/@nodeName"/> </a> </li> <xsl:for-eachselect="$currentPage/ancestor-or-self::* [@isDoc and @level=$level]/* [@isDoc and string(umbracoNaviHide) != '1']"> <li> <ahref="{umbraco.library:NiceUrl(@id)}"> <xsl:iftest="$currentPage/ancestor-or-self::*/@id = current()/@id">
<xsl:attributename="class">selected</xsl:attribute> </xsl:if> <xsl:value-ofselect="@nodeName"/> </a> </li> <xsl:iftest="$currentPage/ancestor-or-self::*/@id = current()/@id and @isDoc "> <ul> <xsl:for-eachselect="$currentPage/ancestor-or-self::* [@isDoc and @level>$level]/* [@isDoc and string(umbracoNaviHide) != '1']"> <li> <ahref="{umbraco.library:NiceUrl(@id)}"> <xsl:iftest="$currentPage/ancestor-or-self::*/@id = current()/@id">
If you want to show the two nodes under Products when you are on that page, and the two nodes under Portfolio when you are on that node, I'm pretty sure that you can just change the level-variable from 1 to 2. In the code you show above, the menu will show nodes under your level 1 node - which are the Home-node.
I am getting the correct root node, changing the code to your method doesn't change the output of the XSLT.
Kim,
Changing the level variable from 1 to 2 results in there being no navigation apart from the homepage item which is hard coded in.
I want to use this 1 XSLT to run the whole navigation, so i don't want one for the level 1 and another instance of it to show level 2. i want them all incorporated in one XSLT.
this XSLT i have does do what i want for the sub menu's but when i am on the About us Page, it thinks that Products etc are sub pages of about us rather than at the same level and i'm not sure why.
Could you try changing your select-statement from this:
$currentPage/ancestor-or-self::* [@isDoc and @level>$level]/* [@isDoc and string(umbracoNaviHide) != '1']
To this:
$currentPage/ancestor-or-self::*[@level=2]/* [@isDoc and string(umbracoNaviHide) != '1']
This should still render your top navigation, and then create the level 2 navigation if the current page has some children to render. It's just from the top of my head, so please bare with me if it's not what you want to achieve 100% :)
I just came upon this thread while searching the forum, and it proved to be the solution I was looking for.
Here's what I'd love, if anyone actually has the time to do it: Could someone comment the xslt in this example to explain what each line does and how the syntax achieves it?
I'm trying to learn xslt right now, and real-world examples tend to be much more useful than <book><chapter><page> type examples.
Thanks to anyone who reads and responds to this post!
Sub Navigation
Hi,
Noobie question here, i have scoured the forum trying to sort this but can't find what i need.
Umbraco 4.5.2, Windows IIS 6, ASP .NET 4.0
I have the following structure, like most people:
Home
About Us
Products
Prod 1
Prod 2
Portfolio
Port 1
Port 2
I only want to show sub levels when i'm on the products page or portfolio page. The XSLT i have seems to work ok for that but when i go to the about us page, it thinks products and portfolio are sub levels to about us.
I have only been using Umbraco a week so i'm not sure what i'm missing and hoping someone will be able to help me.
<?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"/>
<!-- Input the documenttype you want here -->
<!-- Typically '1' for topnavigtaion and '2' for 2nd level -->
<!-- Use div elements around this macro combined with css -->
<!-- for styling the navigation -->
<xsl:variable name="level" select="1"/>
<xsl:variable name="siteRoot" select="$currentPage/ancestor-or-self::*[@level = 1]" />
<xsl:template match="/">
<!-- The fun starts here -->
<ul>
<li>
<a href="{umbraco.library:NiceUrl($siteRoot/@id)}">
<xsl:value-of select="$currentPage/ancestor-or-self::*/@nodeName"/>
</a>
</li>
<xsl:for-each select="$currentPage/ancestor-or-self::* [@isDoc and @level=$level]/* [@isDoc and string(umbracoNaviHide) != '1']">
<li>
<a href="{umbraco.library:NiceUrl(@id)}">
<xsl:if test="$currentPage/ancestor-or-self::*/@id = current()/@id">
<xsl:attribute name="class">selected</xsl:attribute>
</xsl:if>
<xsl:value-of select="@nodeName"/>
</a>
</li>
<xsl:if test="$currentPage/ancestor-or-self::*/@id = current()/@id and @isDoc ">
<ul>
<xsl:for-each select="$currentPage/ancestor-or-self::* [@isDoc and @level>$level]/* [@isDoc and string(umbracoNaviHide) != '1']">
<li>
<a href="{umbraco.library:NiceUrl(@id)}">
<xsl:if test="$currentPage/ancestor-or-self::*/@id = current()/@id">
<xsl:attribute name="class">subselected</xsl:attribute>
</xsl:if>
<xsl:value-of select="@nodeName"/>
</a>
</li>
</xsl:for-each>
</ul>
</xsl:if>
</xsl:for-each>
</ul>
</xsl:template>
</xsl:stylesheet>
Thanks
Chris
Hi Chris,
The problem is that you are not finding the correct root.
replace node_id with the ID of the root node
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="level" select="1"/>
<xsl:variable name="siteRoot" select="umbraco.library:GetXmlNodeById('node_id')" />
<xsl:template match="/">
<ul>
<li>
<a href="{umbraco.library:NiceUrl($siteRoot/@id)}">
<xsl:value-of select="$currentPage/ancestor-or-self::*/@nodeName"/>
a>
li>
<xsl:for-each select="$currentPage/ancestor-or-self::* [@isDoc and @level=$level]/* [@isDoc and string(umbracoNaviHide) != '1']">
<li>
<a href="{umbraco.library:NiceUrl(@id)}">
<xsl:if test="$currentPage/ancestor-or-self::*/@id = current()/@id">
<xsl:attribute name="class">selectedxsl:attribute>
xsl:if>
<xsl:value-of select="@nodeName"/>
a>
li>
<xsl:if test="$currentPage/ancestor-or-self::*/@id = current()/@id and @isDoc ">
<ul>
<xsl:for-each select="$currentPage/ancestor-or-self::* [@isDoc and @level>$level]/* [@isDoc and string(umbracoNaviHide) != '1']">
<li>
<a href="{umbraco.library:NiceUrl(@id)}">
<xsl:if test="$currentPage/ancestor-or-self::*/@id = current()/@id">
<xsl:attribute name="class">subselectedxsl:attribute>
xsl:if>
<xsl:value-of select="@nodeName"/>
a>
li>
xsl:for-each>
ul>
xsl:if>
xsl:for-each>
ul>
xsl:template>
xsl:stylesheet>
Also, you can create a macro, and pass the rootnode as a parameter.
HTH.
Sincere regards,
Eduardo Macho
Hi Chris
If you want to show the two nodes under Products when you are on that page, and the two nodes under Portfolio when you are on that node, I'm pretty sure that you can just change the level-variable from 1 to 2. In the code you show above, the menu will show nodes under your level 1 node - which are the Home-node.
/Kim A
Thank you both for your answers.
Eduardo,
I am getting the correct root node, changing the code to your method doesn't change the output of the XSLT.
Kim,
Changing the level variable from 1 to 2 results in there being no navigation apart from the homepage item which is hard coded in.
I want to use this 1 XSLT to run the whole navigation, so i don't want one for the level 1 and another instance of it to show level 2. i want them all incorporated in one XSLT.
this XSLT i have does do what i want for the sub menu's but when i am on the About us Page, it thinks that Products etc are sub pages of about us rather than at the same level and i'm not sure why.
does this help?
Thanks
Chris
I suspect i need to count the number of sub nodes for the page i am on and if it's greater than 0 enter the second if.
Can someone tell me how to achieve this?
I am getting the following output:
Thanks
Chris
Ohh, I think I was a bit to fast before.
Could you try changing your select-statement from this:
$currentPage/ancestor-or-self::* [@isDoc and @level>$level]/* [@isDoc and string(umbracoNaviHide) != '1']
To this:
$currentPage/ancestor-or-self::*[@level=2]/* [@isDoc and string(umbracoNaviHide) != '1']
This should still render your top navigation, and then create the level 2 navigation if the current page has some children to render. It's just from the top of my head, so please bare with me if it's not what you want to achieve 100% :)
/Kim A
And another thing, like you mention yourself. Try changing your if-statement from this:
$currentPage/ancestor-or-self::*/@id = current()/@id and @isDoc
to this:
count(./*[@isDoc])>0 and count(descendant-or-self::*[@id = $currentPage/@id]) > 0
/Kim A
I just came upon this thread while searching the forum, and it proved to be the solution I was looking for.
Here's what I'd love, if anyone actually has the time to do it: Could someone comment the xslt in this example to explain what each line does and how the syntax achieves it?
I'm trying to learn xslt right now, and real-world examples tend to be much more useful than <book><chapter><page> type examples.
Thanks to anyone who reads and responds to this post!
Dana
is working on a reply...