<!-- update this variable on how deep your site map should be -->
<xsl:variable name="maxLevelForSitemap" select="4"/>
<xsl:template match="/">
<div class="nav-super">
<xsl:call-template name="drawNodes">
<xsl:with-param name="parent" select="$currentPage/ancestor-or-self::* [@isDoc and @level=1]"/>
</xsl:call-template>
</div>
</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/* [@isDoc and string(umbracoNaviHide) != '1' and @level <= $maxLevelForSitemap]">
<li>
<a href="{umbraco.library:NiceUrl(@id)}">
<xsl:value-of select="@nodeName"/>
</a>
<xsl:if test="count(./* [@isDoc and string(umbracoNaviHide) != '1' and @level <= $maxLevelForSitemap]) > 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>
However, when I'm on the Church page, that doesn't have children, the child pages of School show. I only want those to show when I'm on the School page.
I just looked at an old site I have lying around that still uses XSLT.
I have a parameter in my xslt like this
<xsl:param name="currentPage"/>
I think this get's auto populated by Umbraco, because I don't see it being set in the template where I call the macro
And then to test if i'm on the current page I do this. It checks if the id of the currentPage param is equal to the current one from the in the for-each
<xsl:if test="$currentPage/@id=current()/@id">
<!-- your logic here -->
</xsl:if>
Is there a specific reason you're using XSLT if you're new to Umbraco? XSLT is more of a legacy language for Umbraco at this point, you're much better off working in C# if you plan to work on new Umbraco sites.
Primarily due to the fact that this site and the majority of the other sites I'm working with use XSLT for nearly everything. I won't be building new Umbraco sites, rather working with legacy sites on Umbraco 7 and below.
Yes, Dave! It got me half way there. The only problem now is I still need to get the 3rd level to show below the current page. Right now it's displaying 1st level for all pages & 2nd levels below the current page, but not the 3rd. I still need to have the nav show the 3rd level below the current page. Here's my current code:
]>
<!-- update this variable on how deep your site map should be -->
<xsl:variable name="maxLevelForSitemap" select="4"/>
<xsl:template match="/">
<div class="nav-desktop">
<xsl:call-template name="drawNodes">
<xsl:with-param name="parent" select="$currentPage/ancestor-or-self::* [@isDoc and @level=1]"/>
</xsl:call-template>
</div>
</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/* [@isDoc and string(umbracoNaviHide) != '1' and @level <= $maxLevelForSitemap]">
<li>
<a href="{umbraco.library:NiceUrl(@id)}">
<xsl:value-of select="@nodeName"/>
</a>
<xsl:if test="$currentPage/@id=current()/@id">
<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>
Here's my take - and I know it's a complete rewrite, but it's ususally easier to tweak, than the "drawNodes" approach you're trying to tweak:
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:umb="urn:umbraco.library"
exclude-result-prefixes="umb"
>
<xsl:output method="html" indent="yes" omit-xml-declaration="yes" />
<xsl:param name="currentPage" />
<xsl:variable name="siteRoot" select="$currentPage/ancestor-or-self::*[@level = 1]" />
<!-- Select the children of the Home/Site (level 1) as first level in navigation -->
<xsl:variable name="rootLevelNodes" select="$siteRoot/*[@isDoc][not(umbracoNaviHide = 1)]" />
<xsl:template match="/">
<ul class="nav">
<!-- Process the selected nodes here -->
<xsl:apply-templates select="$rootLevelNodes" />
</ul>
</xsl:template>
<xsl:template match="*[@isDoc]">
<!-- Select any children of this one -->
<xsl:variable name="childNodes" select="*[@isDoc][not(umbracoNaviHide = 1)]" />
<li>
<a href="{umb:NiceUrl(@id)}">
<xsl:value-of select="@nodeName" />
</a>
<!-- If $currentPage is either this one or below, render any children as subnavigation -->
<xsl:if test="$childNodes and descendant-or-self::*[@id = $currentPage/@id]">
<ul>
<xsl:apply-templates select="$childNodes" />
</ul>
</xsl:if>
</li>
</xsl:template>
</xsl:stylesheet>
This initial version does not handle protected pages, nor does it set a maximum level - I rarely need those, and I never add them in before I need them :)
There are only two templates - the one that handles output and the one that sets it off.
Hope that helps - and let me know if it fails/explodes/works :)
So very close, Chriztian. The 3rd level displays when you're on a 3rd level page, but not when you're on a 2nd level page. I'd like for the 3rd level to display on 2nd level pages as well.
You want to test the ancestor axis too then, like this:
<!-- If $currentPage is either above or below, render any children as sub navigation -->
<xsl:if test="$childNodes and (ancestor::*[@id = $currentPage/@id] or descendant-or-self::*[@id = $currentPage/@id])">
But you need to decide a couple of things:
What happens on the Home (/) page? - How many levels do you want to show there? (If we just look up the ancestor axis we'll get a match on every page in the navigation when we're on the home page).
What happens on the /school/about/ page - do you want to expand Academics there as well? The academics branch is neither on the ancestors or descendants axis so need to maybe look at the level?
/Chriztian
(This is exactly why I always write navigations from scratch - there's always something different :-)
Then here's a full sheet to bring everyone up to speed:
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:umb="urn:umbraco.library"
exclude-result-prefixes="umb"
>
<xsl:output method="html" indent="yes" omit-xml-declaration="yes" />
<xsl:param name="currentPage" />
<xsl:variable name="siteRoot" select="$currentPage/ancestor-or-self::*[@level = 1]" />
<!-- Select the children of the Home/Site (level 1) as first level in navigation -->
<xsl:variable name="rootLevelNodes" select="$siteRoot/*[@isDoc][not(umbracoNaviHide = 1)]" />
<!-- Which section are we in (if any?) -->
<xsl:variable name="currentSection" select="$currentPage/ancestor-or-self::*[@level = 2]" />
<xsl:template match="/">
<ul class="nav">
<!-- Process the selected nodes here -->
<xsl:apply-templates select="$rootLevelNodes" />
</ul>
</xsl:template>
<xsl:template match="*[@isDoc]">
<!-- Select any children of this one -->
<xsl:variable name="childNodes" select="*[@isDoc][not(umbracoNaviHide = 1)]" />
<!-- Are we inside the "current" section? -->
<xsl:variable name="inCurrentSection" select="ancestor-or-self::*[@id = $currentSection/@id]" />
<!-- Are we in the "currentPage" branch? -->
<xsl:variable name="inCurrentPageBranch" select="ancestor::*[@level > $siteRoot/@level][@id = $currentPage/@id] or descendant-or-self::*[@id = $currentPage/@id]" />
<li>
<a href="{umb:NiceUrl(@id)}">
<xsl:value-of select="@nodeName" />
</a>
<!-- Should we show the children? -->
<xsl:if test="$childNodes and ($inCurrentPageBranch or $inCurrentSection)">
<ul>
<xsl:apply-templates select="$childNodes" />
</ul>
</xsl:if>
</li>
</xsl:template>
</xsl:stylesheet>
XSLT Multi Level Nav
I'm new to Umbraco and trying to build a simple UL menu with child pages that show under the current page. For example:
Here is my XSLT
However, when I'm on the Church page, that doesn't have children, the child pages of School show. I only want those to show when I'm on the School page.
Any help would be greatly appreciated. Thanks!
Hi Tony,
I just looked at an old site I have lying around that still uses XSLT.
I have a parameter in my xslt like this
I think this get's auto populated by Umbraco, because I don't see it being set in the template where I call the macro
And then to test if i'm on the current page I do this. It checks if the id of the currentPage param is equal to the current one from the in the for-each
Dave
According to the docs the currentPage parameter get's populated by Umbraco
https://our.umbraco.org/documentation/reference/templating/macros/xslt/The-Basics
Is there a specific reason you're using XSLT if you're new to Umbraco? XSLT is more of a legacy language for Umbraco at this point, you're much better off working in C# if you plan to work on new Umbraco sites.
Primarily due to the fact that this site and the majority of the other sites I'm working with use XSLT for nearly everything. I won't be building new Umbraco sites, rather working with legacy sites on Umbraco 7 and below.
Hi Tony,
Did my earlier reply help you out ?
Dave
Yes, Dave! It got me half way there. The only problem now is I still need to get the 3rd level to show below the current page. Right now it's displaying 1st level for all pages & 2nd levels below the current page, but not the 3rd. I still need to have the nav show the 3rd level below the current page. Here's my current code:
]>
Maybe you should set the
maxLevelForSitemap
one higher ?Dave
Nope, that didn't do it.
Hi Tony,
I think this check is the culprit :
It will only render items when the current item on level 1 is the same as the visited page.
So this check needs to be extended. I have been looking in some xslt files from a site that still runs v4 of umbraco
Add this at the top of your xslt :
And then update the test like this :
Let me know if that works.
Dave
Thanks for your help, Dave. I appreciate it. However, still no luck displaying the 3rd level. Here's the updated code per your suggestions:
I'm going to call in some help from a xslt expert.
Dave
Hi Tony,
Here's my take - and I know it's a complete rewrite, but it's ususally easier to tweak, than the "drawNodes" approach you're trying to tweak:
This initial version does not handle protected pages, nor does it set a maximum level - I rarely need those, and I never add them in before I need them :)
There are only two templates - the one that handles output and the one that sets it off.
Hope that helps - and let me know if it fails/explodes/works :)
/Chriztian
So very close, Chriztian. The 3rd level displays when you're on a 3rd level page, but not when you're on a 2nd level page. I'd like for the 3rd level to display on 2nd level pages as well.
Great - just to be sure: it does display 3rd level if the 2nd level page you’re on has children, right?
When you're on a 2nd level page, it does not display the 3rd level if the 2nd level page has children.
It does, however, display the 3rd level when on the 3rd level page.
Here's a visual:
http://2018.stjn.org.172-24-16-245.leinteractive.com/school/ - 2nd level page - missing drop down below Academics
http://2018.stjn.org.172-24-16-245.leinteractive.com/school/academics/ - 3rd level page - drop down is properly showing below Academics. I'd like this dropdown to also show on 2nd level pages.
I can’t believe it ;)
Can you post the code? Something’s not right - if I run that on a standard structure it works as intended ...
/Chriztian
Actually, now I get it - you want 4th level pages to show when you’re on a 2nd level page, which this does not do... ?
I suppose that is technically the 4th level. ;)
Say I'm on /school. Currently, it displays /school/academics in the nav. But I need it display 1 level deeper. i.e. /school/academics/preschool.
When I go to /school/academics, it is showing /school/academics/preschool in the nav.
No problem :)
You want to test the ancestor axis too then, like this:
But you need to decide a couple of things:
What happens on the Home (/) page? - How many levels do you want to show there? (If we just look up the ancestor axis we'll get a match on every page in the navigation when we're on the home page).
What happens on the /school/about/ page - do you want to expand Academics there as well? The academics branch is neither on the ancestors or descendants axis so need to maybe look at the level?
/Chriztian
(This is exactly why I always write navigations from scratch - there's always something different :-)
Now it's really real close :)
Alrighty!
Then here's a full sheet to bring everyone up to speed:
Hope the additions make sense,
/Chriztian
I owe you a beer...or beers. That code works great. Hit me up if you're ever in Minnesota, USA!
Thank you VERY much for your help.
is working on a reply...