Automatic YUI Menu Navigation Options
VirtualRichard
Posted: Sunday, May 04, 2008 3:30:48 PM

Rank: Aficionado

Joined: 9/17/2007
Posts: 198
Location: London, UK.
I've been working on taking the site structure for a site I am working on and representing that as an interactive menu. It's complete in that it's working with the following structure:

Home
-Section
--Sub Section
-Section
--Sub Section
-Section
--Sub Section
.etc...

The idea is to have a horizontal meny like this. Get hold of YUI here.

Here's how I created my menu.

In Umbraco, create a basic page template. The doctype is critical. Replace "YOUR_CONTAINER" with whatever you name your root content item (in my example, mine would be 'home'..

Code:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
    <title>Test</title>
    <link href="/YUI/reset-fonts-grids/reset-fonts-grids.css" rel="stylesheet" type="text/css">
    <link href="/YUI/menu/assets/skins/umbracodocs/menu.css" rel="stylesheet" type="text/css">
    <script src="/YUI/yahoo-dom-event/yahoo-dom-event.js" type="text/javascript"></script>
    <script src="/YUI/container/container_core.js" type="text/javascript"></script>
    <script src="/YUI/menu/menu.js" type="text/javascript"></script>
        <script type="text/javascript">
    YAHOO.util.Event.onContentReady("YOUR_CONTAINER", function ()
    {
        var oMenuBar = new YAHOO.widget.MenuBar("YOUR_CONTAINER",
        {
            autosubmenudisplay:true,
            hidedelay:500,
            lazyload:true
        });
                oMenuBar.render();
    });
        </script>
</head>
<body id="yahoo-com">

<?UMBRACO_MACRO macroAlias="MajorNav" ></?UMBRACO_MACRO>

</body>
</html>


Next, create a new clean stylesheet together with a macro, called MajorNav. This is the code I used and is based in turn from the included sitemap / navigation stylesheets in Umbraco:

Code:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xsl:Stylesheet [ <!ENTITY nbsp "&#x00A0;"> ]>
<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"
    exclude-result-prefixes="msxml umbraco.library">

    <xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>
    <xsl:param name="currentPage"/>
    <xsl:variable name="maxLevelForSitemap" select="4"/>

    <xsl:template match="/">

        <!--xsl:copy-of select="$currentPage"/-->
        <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:copy-of select="$parent"/-->

        <div id="majorNav">
            <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)">
                <div id="{$parent/@urlName}" class="yuimenubar yuimenubarnav">
                    <div class="bd">
                        <xsl:element name="ul">
                            <xsl:if test="position() = 1">
                                   <xsl:attribute name="class">first-of-type</xsl:attribute>
                            </xsl:if>
                            <xsl:for-each select="$parent/node [string(./data [@alias='umbracoNaviHide']) != '1' and @level &lt;= $maxLevelForSitemap]">

                                <xsl:element name="li">
                    <xsl:choose>
                        <xsl:when test="position() = 1">
                            <xsl:attribute name="class">yuimenubaritem first-of-type</xsl:attribute>
                        </xsl:when>
                        <xsl:otherwise>
                            <xsl:attribute name="class">yuimenubaritem</xsl:attribute>
                        </xsl:otherwise>
                    </xsl:choose>
                    <a class="yuimenubaritemlabel" href="{umbraco.library:NiceUrl(@id)}"><xsl:value-of select="@nodeName"/></a>
                                        <xsl:if test="count(./node [string(./data [@alias='umbracoNaviHide']) != '1' and @level &lt;= $maxLevelForSitemap]) &gt; 0">
                                            <xsl:call-template name="drawNodes2">
                                                <xsl:with-param name="parent" select="."/>
                                            </xsl:call-template>
                                        </xsl:if>
                                </xsl:element>

                            </xsl:for-each>
                        </xsl:element>
                    </div>
                </div>
            </xsl:if>
        </div>

    </xsl:template>

    <xsl:template name="drawNodes2">

        <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)">
            <div id="{@urlName}" class="yuimenu">
                <div class="bd">
                    <ul>
                        <xsl:for-each select="$parent/node [string(./data [@alias='umbracoNaviHide']) != '1' and @level &lt;= $maxLevelForSitemap]">
                            <li class="yuimenuitem"><a class="yuimenuitemlabel" href="{umbraco.library:NiceUrl(@id)}"><xsl:value-of select="@nodeName"/></a>
                                <xsl:if test="count(./node [string(./data [@alias='umbracoNaviHide']) != '1' and @level &lt;= $maxLevelForSitemap]) &gt; 0">
                                    <ul>
                                        <xsl:call-template name="drawNodes3">
                                            <xsl:with-param name="parent" select="."/>
                                        </xsl:call-template>
                                    </ul>
                                </xsl:if>
                            </li>
                        </xsl:for-each>
                    </ul>
                </div>
            </div>
        </xsl:if>

    </xsl:template>

    <xsl:template name="drawNodes3">

        <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)">
            <xsl:for-each select="$parent/node [string(./data [@alias='umbracoNaviHide']) != '1' and @level &lt;= $maxLevelForSitemap]">
                <li class="yuimenuitem"><a class="yuimenuitemlabel" href="{umbraco.library:NiceUrl(@id)}"><xsl:value-of select="@nodeName"/></a>
                <xsl:if test="count(./node [string(./data [@alias='umbracoNaviHide']) != '1' and @level &lt;= $maxLevelForSitemap]) &gt; 0">
                    <xsl:call-template name="drawNodes2">
                        <xsl:with-param name="parent" select="."/>
                    </xsl:call-template>
                </xsl:if>
                </li>
            </xsl:for-each>
        </xsl:if>

    </xsl:template>

</xsl:stylesheet>


Ever keen to point out my lack of superbness in XSLT, think of this as Beta 1 and most assuredly in need of improvement :d/

I haven't tested it further than a couple of levels yet but with the above I have a cool looking extendable horizontal navigation to play with.

Future work could include adding properties to the Macro to manipulate the layout of the menu (look at the YUI Menu examples for ideas). You might even include a source url as a content picker to allow you to make menus of any part(s) of your site.

In my mind this example illustrates one of the key benefits of Umbraco as it helps me to create advanced site features using non-Umbraco tools such as YUI instead of locking me into a vendor-specific method.

Hope this is of interest.

Richard

2 * 3 * 3 * 37 : The prime factorisation of The Beast.
Prle
Posted: Sunday, May 11, 2008 5:35:20 AM
Rank: Newbie

Joined: 6/29/2007
Posts: 24
Location: Zagreb, Croatia
Hi Richard,

you can have to same effect using the jdMenu (http://jdsharp.us/jQuery/plugins/jdMenu/). And the plus side of this menu is that html consists of just some nested list so you can use sitemap xslt for it rather than doing this much xslt coding.
VirtualRichard
Posted: Monday, May 12, 2008 11:20:16 AM

Rank: Aficionado

Joined: 9/17/2007
Posts: 198
Location: London, UK.
I use the YUI menu because it's been tested by Yahoo on just about every browser out there (and then some). It's bullet-proof and I know any issues that are found will be fixed by Yahoo. It's like having my own little uber dev team :)

The XSLT can probably be simplified but half the reason I did it was to see if I could. Techies, huh? ;)

I'm even more sold on jQuery than YUI but sometimes one is a better fit for me than the other.

Richard


2 * 3 * 3 * 37 : The prime factorisation of The Beast.
vonlinaa
Posted: Friday, May 23, 2008 10:14:31 AM
Rank: Aficionado

Joined: 7/23/2006
Posts: 171
Great work Richard

Wrap it up and make a package Applause
http://umbraco.org/blog/2008/5/7/make-a-package---win-an-xbox-360-with-rockband

Søren Linaa
Level 1 & 2 Certified Professional
VirtualRichard
Posted: Monday, June 02, 2008 3:29:49 PM

Rank: Aficionado

Joined: 9/17/2007
Posts: 198
Location: London, UK.
Just saw this. I would love to make a package but you know how it goes with the rl job sucking up all your time as the project deadline heaves itself over the rapidly approaching horizon...

I'll keep it in mind!

Richard

2 * 3 * 3 * 37 : The prime factorisation of The Beast.
Users browsing this topic
Guest


You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.