Copied to clipboard

Flag this post as spam?

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


  • Anette 41 posts 59 karma points
    Oct 15, 2009 @ 15:56
    Anette
    0

    Expanding menu help

    Hi,

     

    I've a problem with a menu. Looks like this

    Node level 3

    - node level 4

    - node level 4

    - - node level 5

    - - - node level 6

    - - node level 5
    Node level 3

    Node level 3

    - Node level 4

    I have some xslt that either expand all or expand a level 3 node so the level 4 nodes are visible, but I want all the child nodes visible if there are any, so that if level 4 are visible and have child node they should be visible too. (I can change between the two with changing a 0 to 1).

    The existing xslt is not something I wrote but something I have modified, and I'm not sure I understand enough to solve this... I really hope someone can help me!

    Here is the xslt:

    <?xml version="1.0" encoding="utf-8"?>
    <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="html"/>
      <xsl:param name="currentPage"/>
    <xsl:variable name="maxLevel" select="5"/>
    <xsl:variable name="minLevel" select="2"/>

      <xsl:template match="/">
        <div id="navigationmenu">
          <xsl:call-template name="drawNodes">
            <xsl:with-param name="current" select="$currentPage/ancestor-or-self::node [@level=1]"/>
            <xsl:with-param name="level" select="2"/>
            <xsl:with-param name="openpage" select="$currentPage"/>
          </xsl:call-template>
        </div>
      </xsl:template>

      <xsl:template name="drawNodes">
        <xsl:param name="current"/>
        <xsl:param name="openpage"/>
        <xsl:param name="level"/>
        <xsl:param name="active">
          <xsl:choose>
            <xsl:when test="count($openpage/ancestor-or-self::node) &gt; 0">
              <xsl:call-template name="isInSubmenu">
                <xsl:with-param name="list" select="$openpage/ancestor-or-self::node"/>
                <xsl:with-param name="pos" select="1"/>
                <xsl:with-param name="curpagename" select="$current/@id"/>
              </xsl:call-template>
            </xsl:when>
            <xsl:otherwise>
              1
            </xsl:otherwise>
          </xsl:choose>
        </xsl:param>
        <xsl:if test="$active=1">
          <ul>
            <xsl:if test="$level = 1">
              <li>
      <a href="/" class="menu_level1">
                      <xsl:value-of select="$current/@nodeName"/>
      </a>
              </li>
            </xsl:if>
            <xsl:for-each select="$current/node [string(data [@alias='manual']) = '1']">
              <li>
                <xsl:choose>
                  <xsl:when test="@id=$openpage/@id">
                    <a href="{umbraco.library:NiceUrl(@id)}" class="selected">
      <xsl:if test="@level &gt;= '3'">
      <xsl:for-each select="$currentPage/ancestor::node [@level &gt; $minLevel and string(data [@alias='manual']) = '1']">
                  <xsl:value-of select="@sortOrder + 1"/>.</xsl:for-each><xsl:value-of select="$currentPage/@sortOrder + 1"/>.
      </xsl:if>
      <xsl:text>&#xA0;</xsl:text>
      <xsl:value-of select="@nodeName"/>
                    </a>
                  </xsl:when>
                  <xsl:otherwise>
             <a href="{umbraco.library:NiceUrl(@id)}">
      <xsl:if test="@level = '3'">
      <xsl:attribute name="class">
      <xsl:text>menu</xsl:text>
      </xsl:attribute>
      </xsl:if>
      <xsl:if test="@level &gt;= '3'">
      <xsl:for-each select="./ancestor::node [@level &gt; $minLevel and string(data [@alias='manual']) = '1']">
                  <xsl:value-of select="@sortOrder + 1"/>.</xsl:for-each><xsl:value-of select="./@sortOrder + 1"/>.

      </xsl:if>
      <xsl:text>&#xA0;</xsl:text>
                      <xsl:value-of select="@nodeName"/>
                    </a>
                  </xsl:otherwise>
                </xsl:choose>
                <xsl:call-template name="drawNodes">
                  <xsl:with-param name="current" select="."/>
                  <xsl:with-param name="openpage" select="$openpage"/>
                  <xsl:with-param name="level" select="$level + 1"/>
                </xsl:call-template>
              </li>
            </xsl:for-each>
          </ul>
        </xsl:if>
      </xsl:template>

     <xsl:template name="isInSubmenu">
        <xsl:param name="list"/>
        <xsl:param name="pos"/>
        <xsl:param name="curpagename"/>
        <xsl:variable name="curitemname" select="$list[$pos]/@id"/>
        <xsl:choose>
          <xsl:when test="$curitemname != $curpagename">
            <xsl:choose>
     <xsl:when test="$pos &lt; count($list)">
     <xsl:call-template name="isInSubmenu">
                  <xsl:with-param name="list" select="$list"/>
                  <xsl:with-param name="pos" select="$pos + 1"/>
                  <xsl:with-param name="curpagename" select="$curpagename"/>
                </xsl:call-template>
              </xsl:when>
              <xsl:otherwise>
                0
              </xsl:otherwise>
            </xsl:choose>
          </xsl:when>
          <xsl:otherwise>
            1
          </xsl:otherwise>
        </xsl:choose>
      </xsl:template>

    </xsl:stylesheet>

     

  • Tim 225 posts 690 karma points
    Oct 15, 2009 @ 17:09
    Tim
    0

    I'm not 100% clear what you are trying to achieve.

    Do you want to expand all nodes below a specific level 2 node (i.e. levels 3 and above)

    For example:

    Level 1 (not shown)

    Level 2 (user is on this page, level 3, 4 and 5 are shown in the navigation) (not shown)

    Level 3 (shown)

    Level 4 (shown)

    Level 5 (shown)

    Level 3 (shown)

    Level 4(shown)

    Level 2 (not shown)

    etc....

    If so check out this package 

    Or are you after something more sophisticated?

    T

  • Anette 41 posts 59 karma points
    Oct 16, 2009 @ 08:33
    Anette
    0

    Hi Tim, I have tried your package, but I can't get it to do what I want...

    Hmm... I'll try to explain it better... I want all the level 1 shown all the time, but when a user click on a level 1 all the child levels are shown:

    Level 1 (shown)

    Level 1 (shown) <-- user is on this page

           Level 2(shown) 

               Level 3 (shown)

                   Level 4 (shown)

              Level 3(shown)

         Level 2 (shown)

        Level 2 (shown)

    Level 1 (shown)

       Level 2 (not shown)

         Level 3 (not shown)

    Level 1 (shown)

        Level 2 (not shown)

    Level 1 (shown)

    etc...

    I hope it's clearer now.

     

    Anette

     

  • Anette 41 posts 59 karma points
    Oct 16, 2009 @ 14:04
    Anette
    0

    I was thinking it should be someting like testing what level 1 node the active page(node) is under and then somhow get it to show all the childnodes to that level 1 node, but not the others...

    I just don't know how or if the above can be done...

    Some pointers would be nice.

    Thanks

    Anette

  • Jacob Jensen 29 posts 49 karma points
    Oct 16, 2009 @ 14:57
    Jacob Jensen
    0

    Hi Anette

    Please try add these templates:

    <

     

    xsl:template name="Menu">

    <

     

    xsl:param name="StartLevel" />

    <

     

    ul>

    <

     

    xsl:apply-templates select="$currentPage/ancestor-or-self::root//node[@level = $StartLevel]" mode="menu">

    <

     

    xsl:with-param name="StartLevel" select="$StartLevel" />

    </

     

    xsl:apply-templates>

    </

     

    ul>

    </

     

    xsl:template>

     

    <

     

    xsl:template match="node" mode="menu">

    <

     

    xsl:param name="StartLevel" />

    <

     

    li>

    <

     

    xsl:element use-attribute-sets="menuanchor" name="a">

    <

     

    xsl:value-of select="@nodeName"/>

    </

     

    xsl:element>

    <

     

    xsl:if test="ancestor-or-self::node[@level=2 and $currentPage/@id = descendant-or-self::node/@id] and ./node">

    <

     

    ul>

    <

     

    xsl:apply-templates select="./node" mode="menu" />

    </

     

    ul>

    </

     

    xsl:if>

    </

     

    li>

    </

     

    xsl:template>

     

    <

     

    xsl:attribute-set name="menuanchor">

    <

     

    xsl:attribute name="class">

    <

     

    xsl:value-of select="concat('Level', @level)"/>

    <

     

    xsl:if test="$currentPage/@id = @id">

    <

     

    xsl:value-of select="concat(' Active ', 'ActiveLevel', @level)"/>

    </

     

    xsl:if></xsl:attribute>

    <

     

    xsl:attribute name="href">

    <

     

    xsl:value-of select="umbraco.library:NiceUrl(@id)"/>

    </

     

    xsl:attribute>

    </

     

    xsl:attribute-set>

    And call the template with:

    <

     

    xsl:call-template name="Menu">

    <

     

    xsl:with-param name="StartLevel" select="number(2)" />

    </

     

    xsl:call-template>

     

    /Jacob

  • Jacob Jensen 29 posts 49 karma points
    Oct 16, 2009 @ 14:59
    Jacob Jensen
    0

    Here is the code: http://pastebin.com/d3fa7ca52

  • Tim 225 posts 690 karma points
    Oct 16, 2009 @ 15:03
    Tim
    0

    Hi Anette,

    The package will support what you are trying to acheive:

    <umbraco:Macro startingLevel="1" recurse="1" selectBranches="1" maxMenuDepth="999" ulBaseClass="" branchClass="" selectedClass="" forceNode="" expandChildren="1" forceHome="0" Alias="[COG]Navigation" runat="server"></umbraco:Macro>

    That should do what you are after. The only thing to watch out for is that you may need to have expandChildren="1" set to 0 on your homepage (otherwise it will just expand all the children of that particular node).

    T

  • Anette 41 posts 59 karma points
    Oct 16, 2009 @ 15:06
    Anette
    0

    Hi Jacob,

    I'm not quite sure I understand what you mean I add these templates... where should I add them? To my existing xslt or a new one?

    Thanks

    Anette

  • Jacob Jensen 29 posts 49 karma points
    Oct 16, 2009 @ 15:12
    Jacob Jensen
    0

    Yes just paste em to the bottom of you xslt for the menu, just before the end of the </stylesheet>, and call the menu in this template :<xsl:template match="/">

  • Jacob Jensen 29 posts 49 karma points
    Oct 16, 2009 @ 15:52
    Jacob Jensen
    0

    oops, please edit
    <xsl:if test="ancestor-or-self::node[@level=2 and $currentPage/@id = descendant-or-self::node/@id] and ./node">

    to use the $StartLevel parameter:

    <xsl:if test="ancestor-or-self::node[@level=$StartLevel and $currentPage/@id = descendant-or-self::node/@id] and ./node">

  • Anette 41 posts 59 karma points
    Oct 19, 2009 @ 09:51
    Anette
    0

    Hi again,

    Sorry for the wait but I couldn't test your code until today.

    Jacob,

    I put your code in my existing xslt, but it only shows the level 2 nodes with all the level 3 nodes visible not the level 4, and 5, etc....

     

    Tim,

    I tried your solution, but it only shows the next level childnodes and not all of them...

     

    Anette

  • Tim 225 posts 690 karma points
    Oct 19, 2009 @ 13:08
    Tim
    0

    Hi Anette,

    It's hard to tell why the navigation package is not working for you, without seeing your exact structure or exactly where and how you are inserting the macro.

    I've just run a test here (with the structure I think you have) and all the children and grand children etc were shown.

    The only things I can suggest are that you check that:

    expandChildren="1"

    and that

    maxMenuDepth="999"

    If you have some way of showing the exact structure and template code I can take a look and see if I can help further. 

    T

     

  • Anette 41 posts 59 karma points
    Oct 19, 2009 @ 14:14
    Anette
    0

    Hi Tim,

    I tried again and now it almost works! :o)

    When I'm on a level 2 node all the level 3 nodes and childnodes are shown, but if I go to one of the level 3 nodes the other level 3 nodes isn't expanded anymore... only the one where I'm on a level 4 node...

    Thanks

    Anette

  • Tim 225 posts 690 karma points
    Oct 19, 2009 @ 18:18
    Tim
    0

    Hi Anette,

    I think I'm closer to understanding your requirements now.

    Are you looking for behaviour like this: http://demo.thecogworks.co.uk/

    I'm doing it on level 1 rather than 2 but the principle is the same.

    If it is, then it can be done with the navigation package but you'll need to create some extra templates.

    For this I created one master template and 3 sub templates

    The 3 sub templates are homepage, contentpage1 and contentpage 2.

    In each template I vary the params that are being passed to the macro in order to acheive the desired effect.

    In the homepage I used this:

        <umbraco:Macro
            startingLevel="1"
            recurse="1"
            selectBranches="0"
            maxMenuDepth="1"
            ulBaseClass=""
            branchClass=""
            selectedClass=""
            forceNode=""
            expandChildren="0"
            forceHome="0"
            Alias="[COG]Navigation"
            runat="server">
        </umbraco:Macro>

    Then in Content 1 I used this:

       <umbraco:Macro
    startingLevel="1"
    recurse="1"
    selectBranches="0"
    maxMenuDepth="999"
    ulBaseClass=""
    branchClass=""
    selectedClass=""
    forceNode="1056"
    expandChildren="1"
    forceHome="0"
    Alias="[COG]Navigation"
    runat="server">
    </umbraco:Macro>

    Then in Content 2 I used this:

       <umbraco:Macro
    startingLevel="1"
    recurse="1"
    selectBranches="0"
    maxMenuDepth="999"
    ulBaseClass=""
    branchClass=""
    selectedClass=""
    forceNode="1053"
    expandChildren="1"
    forceHome="0"
    Alias="[COG]Navigation"
    runat="server">
    </umbraco:Macro>

    In the above examples 1056 and 1053 are the IDs of the Leve 1 nodes. By settings these the navigation behaves as if it were on that page all the time. I realise this is a bit of a hack to get it to work and I think you'll be better off writing some custom XSLT (which if I get 5 mins I'll look to do).

    But this might be enough to get you started!

    T

  • Anette 41 posts 59 karma points
    Oct 20, 2009 @ 08:59
    Anette
    0

    Hi Tim,

    Your demo shows what I want, but the templates could get a little crazy as I have 18+ level 1 nodes!

    I really appreciate your help and I hope you'll get 5 mins... :o)

    Thanks

    Anette

  • Jacob Jensen 29 posts 49 karma points
    Oct 20, 2009 @ 12:12
    Jacob Jensen
    0

    Hi.

    Did u see my post at 10/16/2009 3:52:59 PM

    I forgot to remove the hardcoded level 2 in my example.'

    /Jacob

  • Anette 41 posts 59 karma points
    Oct 20, 2009 @ 13:09
    Anette
    0

    Hi Jacob,

    Yes I did see  your post and tried that but it still didn't do what I want it to... if you look at Tim's demo above that is how I want my menu to be.

    Anette

  • Justin Rimmer 2 posts 22 karma points
    Oct 21, 2009 @ 00:19
    Justin Rimmer
    0

    Hi Guys,

    This is a bit of a highjack of the thread but i can find the soln' anywhere else SORRY! (if you know where i might find it pls direct me. I am a newbie).... I want a very similar menu to Anette, and the cogworks package does 90% of what i need (its great thanks)...but what i would like to do is have the level one nodes display custom images for each menu item... the sub menu items would appear as text just as they do now...(Im trying to integrate a nice sprymenu js that I got from Dreamweaver) but i want to generate the content for the menu dynamically.

    So what i need help with is the xslt code that will allow me to insert an <img> in between the <a></a> with a dynamic src to the image (based on the pagename) for only lvl 1 nodes and text for the rest of them. 

     

    So. example

    <ul>
    <li><a href="somepage"><img src="mnu_prdocuts.jpg"></a>
    <ul>
    <li><a href="somepage">subitem1 lvl2</a></li>
    <li><a href="somepage">subitem2 lvl2</a></li>
    <li><a href="somepage">subitem3 lvl2</a></li>
    </ul>
    </li>

    <li><a href="somepage"><img src="mnu_services.jpg"></a>
    <ul>
    <li><a href="somepage">subitem1 lvl2</a></li>
    <li><a href="somepage">subitem2 lvl2</a></li>
    <li><a href="somepage">subitem3 lvl2</a></li>
    </ul>
    </li>
    <li><a href="somepage"><img src="mnu_news.jpg"></a>
    <ul>
    <li><a href="somepage">subitem1 lvl2</a></li>
    <li><a href="somepage">subitem2 lvl2</a></li>
    <li><a href="somepage">subitem3 lvl2</a>
    <ul>
    <li><a href="somepage">subitem1 lvl3</a></li>
    <li><a href="somepage">subitem2 lvl3</a></li>
    <li><a href="somepage">subitem3 lvl3</a></li>
    </ul>
    </li>
    </ul>

    </li>

    </ul>

     

     

     

  • Justin Rimmer 2 posts 22 karma points
    Oct 22, 2009 @ 02:30
    Justin Rimmer
    0

    Hi Annette,

    If you haven't already found a possible solution I think that I have one for you... I used some code i found in the old umbraco forums.. works like a charm i was even able to insert my images...

    here's the link

    The only thing it requires you to do is add a parameter for the starting node level. Use a content picker as part of the marco that you make and it will traverse all nodes from that point.

    Good Luck!

  • Jake 23 posts 53 karma points
    Oct 28, 2009 @ 22:40
    Jake
    0

    I have done this but my solution requires you to add the nav image to the pagenode for each new secton that you want. Let me know if this would help you.

  • Chriztian Steinmeier 2798 posts 8787 karma points MVP 7x admin c-trib
    Oct 29, 2009 @ 01:52
    Chriztian Steinmeier
    0

    Hi Annette (and others)

    Here's my take on this in XSLT - I've been using something quite similar recently:

    <?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:ms="urn:schemas-microsoft-com:xslt" 
        xmlns:umb="urn:umbraco.library"
        exclude-result-prefixes="ms umb">
    
        <xsl:output method="xml" omit-xml-declaration="yes" />
    
        <xsl:param name="currentPage" />
        <xsl:param name="root" select="$currentPage/ancestor-or-self::root" />
    
        <!-- Specify level to start output at -->
        <xsl:variable name="level" select="'2'" />
    
        <xsl:template match="/">
            <ul>
                <!-- Apply templates to all nodes at specified level -->
                <xsl:apply-templates select="$root/descendant::node[@level = $level]" />
            </ul>
        </xsl:template>
    
        <!-- This is how you want a single node to render -->
        <xsl:template match="node">
            <li>
                <a href="{umb:NiceUrl(@id)}">
                    <xsl:value-of select="@nodeName"/>
                </a>
                <!-- Continue down this branch? -->
                <xsl:if test="descendant-or-self::node = $currentPage and node[data[@alias = 'umbracoNaviHide'] = 0]">
                    <ul>
                        <xsl:apply-templates select="node" />
                    </ul>
                </xsl:if>
            </li>
        </xsl:template>
    
        <!-- Handle nodes explicitly hidden from navigation -->
        <xsl:template match="node[data[@alias = 'umbracoNaviHide'] = 1]" />
    
    
    </xsl:stylesheet>

    /Chriztian

Please Sign in or register to post replies

Write your reply to:

Draft