|
|
Rank: Newbie
Joined: 7/28/2008 Posts: 6 Location: Sweden
|
Hi, i'm new to the forum and to Umbraco. What I'm trying to do is to make a nested navigation. I've used the sample Navigation Prototype and modified it a little. Basically what I'm trying to figure out is how you write a recursive function that'll show a menu item's direct children when it's the selected node. Quote: Example. Bold items are "selected".
Home Services -- Programming ---- XHTML ---- PHP ---- .NET ------ C# ------ VB ---- CSS -- Design -- Web optimisation About Contact
This is my code... Code: <xsl:template match="/">
<!-- The fun starts here -->
<ul> <xsl:for-each select="$currentPage/ancestor-or-self::node [@level=$level]/node [string(data [@alias='umbracoNaviHide']) != '1']"> <li> <a href="{umbraco.library:NiceUrl(@id)}"> <xsl:if test="$currentPage/ancestor-or-self::node/@id = current()/@id"> <xsl:attribute name="class">nav_selected</xsl:attribute> </xsl:if> <xsl:value-of select="@nodeName"/> </a> <xsl:if test="$currentPage/ancestor-or-self::node/@id = current()/@id"> <xsl:if test="$currentPage/ancestor-or-self::node/descendant::node"> <ul> <xsl:for-each select="$currentPage/ancestor-or-self::node [@level=$level+1]/node [string(data [@alias='umbracoNaviHide']) != '1']"> <li> <a href="{umbraco.library:NiceUrl(@id)}"> <xsl:if test="$currentPage/ancestor-or-self::node/@id = current()/@id">
<xsl:attribute name="class">nav_selected</xsl:attribute> </xsl:if> <xsl:value-of select="@nodeName"/> </a> </li> </xsl:for-each> </ul> </xsl:if> </xsl:if> </li> </xsl:for-each> </ul>
</xsl:template>
It's probably an easy fix, but as I'm new to XSLT, XPath, XQuery, Xetcetera it's pretty alien to me, so I'd appreciate any help. Thanks!
|
|
Rank: Newbie
Joined: 7/28/2008 Posts: 10 Location: Stavanger, Norway
|
Maybe this will work for you. Haven't tested it a lot, but it seems to work for me. Code: <xsl:template match="/">
<!-- The fun starts here --> <xsl:call-template name="menu"><xsl:with-param name="level" select="$level"/></xsl:call-template>
</xsl:template>
<xsl:template name="menu">
<xsl:param name="level"/>
<xsl:if test="$currentPage/ancestor-or-self::node/descendant::node"> <ul> <xsl:for-each select="$currentPage/ancestor-or-self::node [@level=$level]/node [string(data [@alias='umbracoNaviHide']) != '1']"> <li> <a href="{umbraco.library:NiceUrl(@id)}"> <xsl:if test="$currentPage/ancestor-or-self::node/@id = current()/@id"> <xsl:attribute name="class">nav_selected</xsl:attribute> </xsl:if> <xsl:value-of select="@nodeName"/> </a> <xsl:if test="$currentPage/ancestor-or-self::node/@id = current()/@id"> <xsl:call-template name="menu"><xsl:with-param name="level" select="$level+1"/></xsl:call-template> </xsl:if> </li> </xsl:for-each> </ul> </xsl:if>
</xsl:template>
|
|
Rank: Newbie
Joined: 7/28/2008 Posts: 6 Location: Sweden
|
Yeah, that works a little better, but I have a problem - if there's no descendants of the selected node it'll place the menu items that are supposed to be on the same level as children. Quote: This is how I want it to be. Bold items are "selected".
Home Services -- Programming ---- XHTML ---- PHP ---- .NET ------ C# ------ VB ---- CSS -- Design -- Web optimisation About Contact
Quote: This is how it turns out. Bold items are "selected".
Home Services -- Programming ---- XHTML ---- PHP ---- .NET ------ C# ------ VB ------ CSS ---- Design ---- Web optimisation -- About -- Contact
As you can see all of the items below the selected item (that has no descendants) are bumped one "menu level".
|
|
Rank: Newbie
Joined: 7/28/2008 Posts: 6 Location: Sweden
|
I think that the problem lies in that Code:<xsl:if test="$currentPage/ancestor-or-self::node/descendant::node"> seems to return true for one level deeper than it should. Any thoughts?
|
|
Rank: Newbie
Joined: 7/28/2008 Posts: 10 Location: Stavanger, Norway
|
I see.. thats a little bug because of an empty list. How about this: Code: <xsl:template name="menu">
<xsl:param name="level"/>
<xsl:if test="count($currentPage/ancestor-or-self::node [@level=$level]/node [string(data [@alias='umbracoNaviHide']) != '1']) > '0'"> <ul> <xsl:for-each select="$currentPage/ancestor-or-self::node [@level=$level]/node [string(data [@alias='umbracoNaviHide']) != '1']"> <li> <a href="{umbraco.library:NiceUrl(@id)}"> <xsl:if test="$currentPage/ancestor-or-self::node/@id = current()/@id"> <xsl:attribute name="class">nav_selected</xsl:attribute> </xsl:if> <xsl:value-of select="@nodeName"/> </a> <xsl:if test="$currentPage/ancestor-or-self::node/@id = current()/@id"> <xsl:call-template name="menu"><xsl:with-param name="level" select="$level+1"/></xsl:call-template> </xsl:if> </li> </xsl:for-each> </ul> </xsl:if>
</xsl:template>
Does that work properly?
|
|
Rank: Newbie
Joined: 7/28/2008 Posts: 6 Location: Sweden
|
Yes, thank you!
Could you explain which lines you edited and what the difference was? I'd appreciate it!
|
|
Rank: Newbie
Joined: 7/28/2008 Posts: 10 Location: Stavanger, Norway
|
marcus.stenbeck wrote:Could you explain which lines you edited and what the difference was? I'd appreciate it! I edited the very line that you pointed out for me. I'm not sure what that test-clause meant before, but now it is true if and only if there are more than 0 children of the "current" node. I use count() to count the children, and > '0' means "greater than 0". So now, if the current node has children, then we'll go on and make a list of them. If current node is child-free, then we don't bother making an empty ul-tag.
|
|
Rank: Newbie
Joined: 7/28/2008 Posts: 6 Location: Sweden
|
Thanks a lot. I just wanted to make sure I didn't miss anything. Cheers!
|
|
Rank: Newbie
Joined: 9/5/2008 Posts: 9 Location: Chattanooga, TN
|
Very Helpful. I just used this post to set up a chromemenu. The MenuItem variable is a true/false box added to the templates, can be removed.
<xsl:template match="/"> <div class="chromestyle" id="topmenu"> <ul> <xsl:for-each select="$currentPage/ancestor::root//node"> <xsl:if test="data [@alias = 'MenuItem'] > 0"> <xsl:if test="@level < 2"> <li> <a href="{umbraco.library:NiceUrl(current()/@id)}"> <xsl:if test="count((current())/node) > '0'"> <xsl:attribute name="rel">menudiv<xsl:value-of select="(current()/@id)" /></xsl:attribute> </xsl:if> <xsl:value-of select="@nodeName"/> </a> </li> </xsl:if> </xsl:if> </xsl:for-each> </ul> </div>
<xsl:for-each select="$currentPage/ancestor::root//node"> <xsl:if test="data [@alias = 'MenuItem'] > 0"> <xsl:if test="@level = 1"> <xsl:if test="count((current())/node) > '0'"> <div id="menudiv{(current()/@id)}" class="dropmenudiv" style="width:150px;"> <xsl:for-each select="(current())/node"> <xsl:if test="data [@alias = 'MenuItem'] > 0"> <xsl:if test="@level = 2"> <a href="{umbraco.library:NiceUrl(current()/@id)}"><xsl:value-of select="@nodeName"/></a> </xsl:if> </xsl:if> </xsl:for-each> </div> </xsl:if> </xsl:if> </xsl:if> </xsl:for-each>
<script type="text/javascript"> cssdropdown.startchrome("topmenu") </script>
</xsl:template>
|
|
 Rank: Devotee
Joined: 8/5/2007 Posts: 95 Location: Bergen, Norway
|
How would you do this of you wanted all the children displayed at once, not when you click the parent node? www.eyecatch.no
|
|
 Rank: Devotee
Joined: 7/6/2007 Posts: 69 Location: Brussels
|
azzlack wrote:How would you do this of you wanted all the children displayed at once, not when you click the parent node? <xsl:if test="$currentPage/ancestor-or-self::node/descendant::node">?
^(B(astia{2}n)?)(\s)?(W(ak{2}ie)?)$ IRC --> irc://irc.freenode.org/umbraco
|
|
|
Guest |