Copied to clipboard

Flag this post as spam?

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


  • RoelAlblas 50 posts 61 karma points
    Apr 09, 2010 @ 21:56
    RoelAlblas
    0

    xslt can be done more simpe, but how?

    Hi,

    I like something to do as the following, but can be done simper and more effective. (its about the level parameter) Any ideas?

     <ul class="ulmenu">
      <xsl:for-each select="$currentPage/ancestor-or-self::node [@level='0']/node [string(data [@alias='umbracoNaviHide']) != '1']">
       <li class="limenu">
        <a href="{umbraco.library:NiceUrl(@id)}" class="notcurrent">
         <xsl:if test="$currentPage/ancestor-or-self::node/@id = current()/@id">
          <xsl:attribute name="class">current</xsl:attribute>
         </xsl:if>
         <xsl:value-of select="@nodeName"/>
        </a>
       </li>
      </xsl:for-each>
      <xsl:for-each select="$currentPage/ancestor-or-self::node [@level='0']/node [string(data [@alias='umbracoNaviHide']) != '1']">
       <li class="limenu">
        <a href="{umbraco.library:NiceUrl(@id)}" class="notcurrent">
         <xsl:if test="$currentPage/ancestor-or-self::node/@id = current()/@id">
          <xsl:attribute name="class">current</xsl:attribute>
         </xsl:if>
         <xsl:value-of select="@nodeName"/>
        </a>
       </li>
      </xsl:for-each>
     </ul>
  • RoelAlblas 50 posts 61 karma points
    Apr 09, 2010 @ 21:58
    RoelAlblas
    0

    Sorry, not clear like this. The second [@level='0']/node has to be [@level='1']/node

  • Peter Dijksterhuis 1442 posts 1722 karma points
    Apr 09, 2010 @ 22:40
    Peter Dijksterhuis
    0

    Hi Roel,

    I think you have 2 options here. First, try a 

    xsl:for-each select="$currentPage/ancestor-or-self::node [@level='0' or @level='1']/node [string(data [@alias='umbracoNaviHide']) != '1']

    You'd only need 1 for each then and you could sort by level perhaphs.

    Secondly, you could try to use a template and call that twice with a different parameter?

    Does this help a bit?

    Peter

  • RoelAlblas 50 posts 61 karma points
    Apr 09, 2010 @ 22:45
    RoelAlblas
    0

    Hi Peter,

    Thanks for your quick reply!

    I've read somewhere that the xslt reads from level 1 instead of level 0. Are there ways around this, so I can get the root of the page also as a item in the menu?

    Could you also give me hint with the following part? This can be done better I think.

    <xsl:if test="$currentPage/ancestor-or-self::node/@id = current()/@id">

  • Lee Kelleher 4020 posts 15802 karma points MVP 13x admin c-trib
    Apr 09, 2010 @ 23:42
    Lee Kelleher
    0

    Hi Roel,

    You can leave out the first <xsl:for-each>, as it will never be hit - there is no "@level='0'" in the XML cache (in \data\umbraco.config), the first level of <node> is "@level=1" (usually the root of your website).

    Then for the "class" attribute of the link, if it's the current page, then you'd be adding 2 "class" attributes; i.e. it would look like this:

    <a href="..." class="notcurrent" class="current">...</a>

    I'd suggest replacing it with an <xsl:choose> condition.  Here's a re-worked snippet:

    <ul class="ulmenu">
        <xsl:for-each select="$currentPage/ancestor-or-self::node[@level='1']/node[string(data[@alias='umbracoNaviHide']) != '1']">
            <li class="limenu">
                <a href="{umbraco.library:NiceUrl(@id)}">
                    <xsl:attribute name="class">
                        <xsl:choose>
                            <xsl:when test="$currentPage/ancestor-or-self::node/@id = @id">current</xsl:when>
                            <xsl:otherwise>notcurrent</xsl:otherwise>
                        </xsl:choose>
                    </xsl:attribute>
                    <xsl:value-of select="@nodeName" />
                </a>
            </li>
        </xsl:for-each>
    </ul>
    

    I'm curious about the "$currentPage/ancestor-or-self::node/@id" part too ... try removing the "ancestor-or-self::node" bit ... but I'm not 100% of your content structure, so it might need it? Play around with it, see what works best!

    Cheers, Lee

  • Chriztian Steinmeier 2798 posts 8788 karma points MVP 7x admin c-trib
    Apr 10, 2010 @ 00:01
    Chriztian Steinmeier
    1

    Hi Roel,

    I'd do something like this:

       <xsl:param name="currentPage" />
        <xsl:variable name="siteRoot" select="$currentPage/ancestor-or-self::node[@level = 1]" />
    
        <xsl:template match="/">
            <ul class="ulmenu">
                <xsl:apply-templates select="$siteRoot | $siteRoot/node" />
            </ul>
        </xsl:template>
    
        <xsl:template match="node">
            <li class="limenu">
                <a href="{umbraco.library:NiceUrl(@id)}" class="notcurrent">
                    <xsl:if test="@id = $currentPage/@id">
                        <xsl:attribute name="class">current</xsl:attribute>
                    </xsl:if>
                    <xsl:value-of select="@nodeName"/>
                </a>
            </li>
        </xsl:template>
    
        <xsl:template match="node[data[@alias = 'umbracoNaviHide'] = 1]" />
    

    The "node" template is your general output (@Lee: Don't worry about duplicate class attributes - XSLT will only generate one, so the second will overwrite the first, if necessary).

    The last (empty) template takes care of nodes with the umbracoNaviHide flag checked

    The "apply-templates" instruction collects the $siteRoot node along with its childnodes, and tell the processor to go do its thing with 'em.

    /Chriztian

     

  • Chriztian Steinmeier 2798 posts 8788 karma points MVP 7x admin c-trib
    Apr 10, 2010 @ 00:10
    Chriztian Steinmeier
    0

    I'll explain the possibilities for setting the "current" class a little bit more in detail:

    If (as I was guessing from the above) the current page will only ever be one of the pages output for navigation (i.e., no level 3 nodes exist) you can do like the above, and check if the @id of the node currently being output is equal to the @id of $currentPage:

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

    If you have subpages (level 3 or more) and you want to keep the current class on the parent nodes of it, check for the presence of currentPage in the descendant-or-self:: axis:

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

    Hope it clears up a couple of things,

    /Chriztian

  • RoelAlblas 50 posts 61 karma points
    Apr 10, 2010 @ 21:44
    RoelAlblas
    0

    Thanks guys! This solves my question!

    Roel

Please Sign in or register to post replies

Write your reply to:

Draft