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 3945 posts 15163 karma points MVP 10x 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 2726 posts 8320 karma points MVP 4x 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 2726 posts 8320 karma points MVP 4x 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

  • This forum is in read-only mode while we transition to the new forum.

    You can continue this topic on the new forum by tapping the "Continue discussion" link below.

Please Sign in or register to post replies