Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • FarmFreshCode 225 posts 422 karma points
    Apr 11, 2011 @ 21:44
    FarmFreshCode
    0

    Dynamic Sub Navigation

    So here is a basic idea of what I am looking to build and an example section of my file tree.

    1.) So first of all this sub navigation should only be displayed IF the level 1 page has sub pages within it. If the page doesn't have any sub pages (like Quick Facts) then nothing should be displayed in this column.

    2.) If you navigate to a page that contains child pages then that level 1 page should be shown at the top.

    3.) If the level 2 page has child pages, should be displayed as illustrated above and contain an extra css style of "submenuheader". 

    1. <a class="menuitem submenuheader" href="orientation.aspx">Orientation</a>

    4.) These level 3 child pages should be listed as a unordered list like this: 

    1. <div class="submenu">
      <ul>
      <li><a href="transfer.aspx">Transfer Students</a></li>
      <li><a href="firsttime.aspx">First Time Students</a></li>
      </ul>
      </div>

    5.) If the level 2 page does not have additional child pages then the link should be displayed with only 1 style applied: 

    1. <a class="menuitem" href="publications.aspx">Publications</a>

    6.) This is just another example of #3 to show how it need to be able to switch back and forth given the circumstances.

    So first I would like to show you a working basic HTML version of how I would like the navigation to work. 

    DEMO HTML VERSION

    Now as far as Umbraco is concerned I have put together the following XSLT file which has got me close, but I have a few things clearly missing. Please review my current XSLT file here:

    <?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" 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 -->
    <xsl:variable name="level" select="1"/>

    <xsl:template match="/">

    <!-- The fun starts here -->
    <xsl:for-each select="$currentPage/ancestor-or-self::* [@level=$level]/* [@isDoc and string(umbracoNaviHide) != '1']">
    <xsl:if test="$currentPage/@id = current()/@id or $currentPage/../@id = current()/@id or $currentPage/../../@id = current()/@id">

    <!-- output navigation HOME -->
    <a class"menuitem" href="{umbraco.library:NiceUrl(@id)}">
    <xsl:value-of select="@nodeName"/>
    </a>

    <!-- 1st navigation items -->
    <xsl:for-each select="./child::* [@isDoc and string(umbracoNaviHide) != '1']">
    <xsl:if test="$currentPage/ancestor-or-self::node/@id = current()/@id"></xsl:if>
    <a class="menuitem submenuheader" href="{umbraco.library:NiceUrl(@id)}">
    <xsl:if test="@id = $currentPage/@id"><xsl:attribute name="class">selected</xsl:attribute></xsl:if>
    <xsl:value-of select="@nodeName"/>
    </a>

    <!--output 2nd level nevigation items -->
    <div class="submenu">
    <ul>
    <!--output 3rd level nevigation items -->
    <xsl:for-each select="./child::* [@isDoc and string(umbracoNaviHide) != '1']">
    <xsl:if test="$currentPage/ancestor-or-self::node/@id = current()/@id"></xsl:if>

    <li>
    <a href="{umbraco.library:NiceUrl(@id)}">
    <xsl:if test="@id = $currentPage/@id"><xsl:attribute name="class">selected</xsl:attribute></xsl:if>
    <xsl:value-of select="@nodeName"/>
    </a>

    </li>

    </xsl:for-each>
    </ul></div>

    </xsl:for-each>
    </xsl:if>
    </xsl:for-each>
    </xsl:template>
    </xsl:stylesheet>

  • FarmFreshCode 225 posts 422 karma points
    Apr 11, 2011 @ 22:11
    FarmFreshCode
    0

    I also forgot to mention that the sub navigation should be exactly the same from the level 1 page all the way through it's level 3l. So as you navigate to say "First Time Students" page, you see the same sub nav as you do on "Publications" which is a level 2 page. Thanks

  • wolulcmit 357 posts 693 karma points
    Apr 12, 2011 @ 00:57
    wolulcmit
    0

    I've a had a wee play and come up with the following: I think it should do what you're wanting.

    <xsl:param name="currentPage"/>

    <xsl:template match="/">
        <div class="glossymenu">
          <!-- match if we have something at level 1 or 2 -->
          <xsl:apply-templates select="$currentPage/ancestor-or-self::*[@level=1]/*[@isDoc]" />
          <xsl:apply-templates select="$currentPage/ancestor-or-self::*[@level=2]/*[@isDoc]" />
          <!--match if we're at the top level (level 0) and we stil want to match for level 1 or 2 -->
          <xsl:apply-templates select="$currentPage/descendant::*[@level=2]/*[@isDoc]" />
        </div>
    </xsl:template>

    <!-- match regardless of level - our normal links -->
    <xsl:template match="*[@isDoc]">
            <xsl:variable name="currentNode" select="."/>
            <!-- only output anything if there are nodes below the currently matched one -->
            <xsl:if test="$currentNode/*[@isDoc]">
            <a class="menuitem" href="{umbraco.library:NiceUrl(@id)}">
                <xsl:value-of select="@nodeName" />
            </a>
            </xsl:if>
    </xsl:template>

        
    <!-- match pages at level 2 - our normal links and submenu if there is one -->
    <xsl:template match="*[@level=2]/*[@isDoc]">
            <xsl:variable name="currentNode" select="."/>
            <a class="menuitem" href="{umbraco.library:NiceUrl(@id)}">
            <!-- output an extra class if there are children below this node -->
            <xsl:if test="$currentNode/*[@isDoc]"><xsl:attribute name="class">menuitem submenuheader</xsl:attribute></xsl:if>  
                <xsl:value-of select="@nodeName" />
            </a>
      
          <!-- only output submenu code if there are children below this node -->
          <xsl:if test="$currentNode/*[@isDoc]">
          <div class="submenu">
            <ul>
            <!-- match pages at level 3 -->
            <xsl:apply-templates select="$currentNode/descendant-or-self::*[@level=3]/*[@isDoc]" />
            </ul>
          </div>
         </xsl:if>
    </xsl:template>

    <!-- match pages at level 3 -->
    <xsl:template match="*[@level=3]/*[@isDoc]">
            <xsl:variable name="currentNode" select="."/>
            <li>
              <a href="{umbraco.library:NiceUrl(@id)}">
                <xsl:value-of select="@nodeName" />
            </a>
            </li>
    </xsl:template>

    <!-- Only output pages that are not hidden -->
    <xsl:template match="*[umbracoNaviHide = 1]" />
  • FarmFreshCode 225 posts 422 karma points
    Apr 12, 2011 @ 13:39
    FarmFreshCode
    0

    @wolulcmit - Thanks for taking a look at it, unfortunately i get errors when I drop in your code. I am using v4.7 if that changes the naming scheme

  • wolulcmit 357 posts 693 karma points
    Apr 12, 2011 @ 14:06
    wolulcmit
    0

    Weird, I'm pretty sure I'm using v4.7 as well.
    my xslt is a little rusty, so I'm sure there are better ways of writing what I wrote.
    I've have posted the full xslt here if it helps..., I tested it and I don't get any errors.

    http://snipplr.com/view/51984/menu-test/

    - Tim

  • FarmFreshCode 225 posts 422 karma points
    Apr 12, 2011 @ 14:23
    FarmFreshCode
    0

    @wolulcmit -ok, actually once I pasted in your full thing it worked.. sorry about that. This was a step in the right direction thanks..  The script is pulling some extra pages.. (see image)

    I'd like this sub nav to only show show Undergrad Services and it's child pages when I navigate to that section. When I move to a different section like... "contact us".. then the sub nav should show Contact us, and it's child pages only...

  • wolulcmit 357 posts 693 karma points
    Apr 12, 2011 @ 14:34
    wolulcmit
    0

    ok - in that case you'll want to change (line 18)

    <!-- match if we have something at level 1 or 2 -->
    <xsl:apply-templates select="$currentPage/ancestor-or-self::*[@level=1]/*[@isDoc]" />

    to:

    <!-- match only on this node -->
    <xsl:apply-templates select="$currentPage/self::*[@level=1]/*[@isDoc]" />

    - Tim

  • FarmFreshCode 225 posts 422 karma points
    Apr 12, 2011 @ 15:13
    FarmFreshCode
    0

    @wolulcmit - Nice! getting there.. when I changed that I lost the "Undergraduate Services" link too though..I'd like to keep that one so that they can get back to the "home page" of the section that they are in..

    THANKS for your help so far

  • FarmFreshCode 225 posts 422 karma points
    Apr 12, 2011 @ 17:50
    FarmFreshCode
    0

    I noticed that when I go to pages that don't have child pages the sub navigations goes away which is great... except for this one line that is still showing up:

    <div class="glossymenu" />

    Which of course throws off my layout.

  • wolulcmit 357 posts 693 karma points
    Apr 12, 2011 @ 19:26
    wolulcmit
    0

    I updated http://snipplr.com/view/51984/menu-test/
    basically, wrapped glossymenu in an xsl:if and added the part for your toplevel.. I hope it works ok!

    we should really ask @greystate (the xslt master) to see how the code I wrote could be improved.
    anyone out there up for demonstrating a razor example of the same thing?

    - Tim

  • FarmFreshCode 225 posts 422 karma points
    Apr 12, 2011 @ 22:41
    FarmFreshCode
    1

    Now we're talking.. thats perfect! Thank you so much! I've only been at this for like 3 weeks (I haven't even touched razor yet) but I hear that razor is the way to go moving forward.. so I would love to see a solution using that as well...

    Thanks again Tim.. I'll give you crazy shoutouts on my blog later today

Please Sign in or register to post replies

Write your reply to:

Draft