Bug 27288

Summary: [PATCH] css-based menu implementation
Product: Lenya Reporter: Gregor J. Rothfuss <gregor>
Component: Navigation FrameworkAssignee: Lenya Developers <dev>
Status: NEW ---    
Severity: enhancement CC: dev
Priority: P3    
Version: Trunk   
Target Milestone: 2.0.1   
Hardware: Other   
OS: other   

Description Gregor J. Rothfuss 2004-02-27 09:01:40 UTC
doug chestnut posted the following alternate menu implementation:

Here is the menu.xsl that I am using for my publications navigation menu
(add the css and javascript to your page2xhtml.xsl):

<?xml version="1.0" encoding="UTF-8" ?>

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:nav="http://apache.org/cocoon/lenya/navigation/1.0"
    xmlns="http://www.w3.org/1999/xhtml"
    exclude-result-prefixes="nav"
    >

<xsl:template match="nav:site">
  <div id="menu"><ul id="navmenu">
    <!-- Static link -->
    <li><a href="http://www.lib.virginia.edu">UVa Library Home</a></li>
    <xsl:apply-templates select="nav:node"/>
  </ul></div>
</xsl:template>

<xsl:template match="nav:node">

  <xsl:choose>
    <!--if last menu item at top level-->
    <xsl:when test="not(ancestor::nav:node) and
not(following-sibling::nav:node)">
      <li id="last"><div>
        <xsl:call-template name="item"/>
      </div>
        <xsl:if test="nav:node">
          <ul class="subnav"><xsl:apply-templates select="nav:node"/></ul>
        </xsl:if>
      </li>
    </xsl:when>
    <!--first sub menu item-->
    <xsl:when test="ancestor::nav:node and
not(preceding-sibling::nav:node)">
      <li id="firstsub"><div>
        <xsl:call-template name="item"/>
      </div>
        <xsl:if test="nav:node">
          <ul class="subnav"><xsl:apply-templates select="nav:node"/></ul>
        </xsl:if>
      </li>
    </xsl:when>
    <xsl:otherwise>
      <li><div>
        <xsl:call-template name="item"/>
      </div>
        <xsl:if test="nav:node">
          <ul class="subnav"><xsl:apply-templates select="nav:node"/></ul>
        </xsl:if>
      </li>
    </xsl:otherwise>
  </xsl:choose>

</xsl:template>

<xsl:template name="item">
    <xsl:choose>
      <xsl:when test="@current = 'true'">
        <xsl:call-template name="item-selected"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:call-template name="item-default"/>
      </xsl:otherwise>
    </xsl:choose>
</xsl:template>

<xsl:template name="item-default">
    <a href="{@href}"><xsl:apply-templates select="nav:label"/></a>
</xsl:template>

<xsl:template name="item-selected">
    <xsl:apply-templates select="nav:label"/>
</xsl:template>

<xsl:template match="nav:label">
  <xsl:value-of select="."/>
</xsl:template>

<xsl:template match="@*|node()">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()"/>
  </xsl:copy>
</xsl:template>

</xsl:stylesheet>

This is the menu that I have been using in my publication:

*****html*****:
<ul id="navmenu">
<li><a href="/">UVa Library Home</a></li>
<li><div><a href="/lab/features.html">Lab Features</a></div>
<ul class="subnav">
<li id="firstsub"><a href="/lab/standards.html">Standards-based Web
Sites</a></li>
<li><a href="/lab/map.html">Map of Library Locations</a></li>
</ul>
</li>
<li><a href="/lab/comments/">Comments</a></li>
<li><a href="/questions.html">Questions</a></li>
<li id="last"><a href="http://virgo.lib.virgiia.edu">VIRGO</a></li>
</ul>

*****css*****:

/* DROP MENUS */

ul#navmenu {
 height: 1.4em;
 position: relative;
 margin: -6px 0 0 -12px;
 padding: 0;
 font-size: 11px;
 list-style: none;
 white-space: nowrap;
}

ul#navmenu  li {
 float: left;
 position:relative;
 width: 6em;
 height: 1.4em;
 background-color: #FFFFEA;
 padding: 0px 12px 0px 4px;
 margin: 0;
 border-top: 1px solid #963;
 border-right: 0px solid #963;
 border-bottom: 1px solid #963;
 border-left: 1px solid #963;
 text-align: left;
}

/* ie 5 mac & win hacks \*/
ul#navmenu li {
 voice-family: "\"}\"";
 voice-family:inherit;
 width: auto;
}

html > body ul#navmenu li {
 width: auto;
}
/* end hacks */

ul#navmenu a {
 font-weight: bold;
 color: #036;
 text-decoration: none;
 margin: 0;
 padding: 0px 8px 2px 4px;
}

ul#navmenu li a:hover {
 text-decoration: underline;
}

ul#navmenu li#last {
 border-right: 1px solid #963;
}

ul#navmenu li ul {
 display: none;
 position: absolute;
 top: 105%; /* value for ie5 */
 left: -1.5em; /* value for ie5 */
 padding: 0;
 margin: 0;
 font-weight: normal;
 list-style: none;
}

/* hack to hide from IE 5 mac & 5-6 \*/
ul#navmenu li ul {
 voice-family: "\"}\"";
 voice-family: inherit;
 left: -0.1em;
}

html > body ul#navmenu li ul {
 left: -0.1em;
}
/*end hacks */

ul#navmenu li ul li {
 display: block;
 float: none;
 margin: 0;
 padding: 2px 4px 2px 4px;
 background-color: #FFFFEA;
 border-top: 0;
 border-right: 1px solid #963;
 border-left: 1px solid #963;
 border-bottom: 1px solid #963;
 white-space: normal;
 height: auto;
 width: 17em;
}

ul#navmenu li ul li a {
 display: block;
 color: #036;
 text-decoration: none;
 height: 12px;
 margin: 0;
 padding: 0;
}

ul#navmenu li ul li a:hover {
 text-decoration: underline;
}

#navmenu li:hover ul, #navmenu li.over ul {
 display: block;
 margin: 0;
}

*****javascript*****:
//hack for CSS dropmenus in IE5x
startList = function() {
 if (document.all&&document.getElementById) {
navRoot = document.getElementById("navmenu");
for (i=0; i<navRoot.childNodes.length; i++) {
node = navRoot.childNodes[i];
if (node.nodeName=="LI") {
node.onmouseover=function() {
this.className+="over";
  }
    node.onmouseout=function() {
  this.className=this.className.replace("over", "");
   }
   }
  }
 }
}
window.onload=startList;

****end****

It is all css (except a few hacks for odd browsers) and best of all it
doesn't use tables (Just a plain old unordered list for the sake of
accessibility).
Comment 1 Gregor J. Rothfuss 2004-11-11 23:39:52 UTC
make sure the dev list is kept in the loop. sorry for the spam.
Comment 2 J 2007-01-04 05:23:29 UTC
this would be a very nice thing to have for 1.4.1.
Comment 3 Andreas Hartmann 2009-01-27 07:51:48 UTC
Has this issue already been addressed?