Copied to clipboard

Flag this post as spam?

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


  • BEWD 89 posts 301 karma points
    Jul 31, 2012 @ 20:28
    BEWD
    0

    repeated navigation using navi.xslt

    Hi All, I am hoping that someone can help me, XSLT is not my strongest subject and I have come across something that I suspect is very simple but I just can't figure it out.

    I have used the Navi.xslt from the 'Building CWS Website' video tutorials and it works fine in some areas, However in one certain area I would like to keep the navigation on the sub page(s) consistent with the page above them. For example the page structure is as follows:

    - Home

    - About Us

                - Location

                - Contact Us

    - Places to eat

                - Place A

                - Place B

                - Place C

    Say for example if you click on 'Place A' I do not want the navigation to change to child pages of 'Place A' I want the navigation to stay constant with the 'Places to Eat' page.

    I would assume that I need to take a copy of the Navi.xslt and make some changes to keep this static for these particular pages which I have tried but I cannot seem to get the code right.

    Is anyone able to advise?

    Cheers

    Ben

  • Chriztian Steinmeier 2798 posts 8788 karma points MVP 7x admin c-trib
    Jul 31, 2012 @ 23:55
    Chriztian Steinmeier
    0

    Hi Ben,

    You shouldn't copy the file and make changes - it's never a good idea to have multiple almost identical files; too many places for stuff to go out of sync :-)

    What you need to figure out (and I don't have the Navi.xslt file here to check) is how to change what is probably one or two XPath selections, in what I assume is an xsl:for-each statement, so they select the correct node(s) to start from.

    Can you put a link to the file somewhere (or if it's less than ~50 lines post it here)?

    /Chriztian

  • BEWD 89 posts 301 karma points
    Aug 01, 2012 @ 00:05
    BEWD
    0

    I agree with the almost identical files comment I just wasnt sure how else to do it. The Navi.xslt is below:

    <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="xml" omit-xml-declaration="yes"/>
      <xsl:param name="currentPage"/>
      <xsl:template match="/">
        <!-- Root Node -->
        <xsl:variable name="rootNode" select="$currentPage/ancestor-or-self::root" />
        <!-- Homepage -->
        <xsl:variable name="homeNode" select="$rootNode/Home [@isDoc]" />
        <ul id="navi">
          <li>
           <!--  Add the CSS class 'selected' if the homeNode ID matches our currentPage node ID -->
            <xsl:if test="$homeNode/@id = $currentPage/@id">
              <xsl:attribute name="class">
                <xsl:text>selected</xsl:text>
              </xsl:attribute>
            </xsl:if>
            <!--Create a link to the homepage -->
            <a href="{umbraco.library:NiceUrl($homeNode/@id)}">
              <xsl:value-of select="$homeNode/@nodeName" />
            </a>
          </li>
         <!-- For each child node of the homeNode that is a document (isDoc)and the level is 2 and the property umbracoNaviHide is NOT 1 (true/checked)-->
          <xsl:for-each select="$homeNode/* [@isDoc and @level = 2 and string(umbracoNaviHide) != '1']">
            <li>
             <!--  Add the CSS class 'selected' if the currentPage or parent nodes (up the tree to the root)ID matches our current node's ID in the for each loop -->
              <xsl:if test="$currentPage/ancestor-or-self::* [@isDoc]/@id = current()/@id">
                <xsl:attribute name="class">
                  <xsl:text>selected</xsl:text>
                </xsl:attribute>
              </xsl:if>
              <!-- Create the link -->
              <a href="{umbraco.library:NiceUrl(@id)}">
                <xsl:value-of select="@nodeName" />
              </a>
            </li>
          </xsl:for-each>
        </ul>
      </xsl:template>
    </xsl:stylesheet>

  • Chriztian Steinmeier 2798 posts 8788 karma points MVP 7x admin c-trib
    Aug 01, 2012 @ 00:31
    Chriztian Steinmeier
    0

    Hi Ben,

    Hmm - that one won't even show pages below level 2... is there a "SubNavi.xslt" or something, that renders the submenus?

    /Chriztian

  • Chriztian Steinmeier 2798 posts 8788 karma points MVP 7x admin c-trib
    Aug 01, 2012 @ 00:38
    Chriztian Steinmeier
    0

    Hi Ben,

    Thought I'd just post one that should do the trick - it's a simple subnav macro, which goes upwards from currentPage to find the current "section" (i.e., a node at level 2, which can easily be changed) and then renders any children below that:

    <?xml version="1.0" encoding="utf-8" ?>
    <xsl:stylesheet
        version="1.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:umb="urn:umbraco.library"
        exclude-result-prefixes="umb"
    >
    
        <xsl:output method="xml" indent="yes" omit-xml-declaration="yes" />
    
        <xsl:param name="currentPage" />
        <xsl:variable name="siteRoot" select="$currentPage/ancestor-or-self::*[@level = 1]" />
        <xsl:variable name="currentSection" select="$currentPage/ancestor-or-self::*[@level = 2]" />
    
        <xsl:template match="/">
            <xsl:if test="$currentSection">
                <ul id="subnavi">
                    <xsl:apply-templates select="$currentSection/*[@isDoc][not(umbracoNaviHide = 1)]" />
                </ul>         
            </xsl:if>
        </xsl:template>
    
        <!-- Generic template for links -->
        <xsl:template match="*[@isDoc]">
            <xsl:variable name="childNodes" select="*[@isDoc][not(umbracoNaviHide = 1)]" />
    
            <li>
                <xsl:if test="@id = $currentPage/@id"><xsl:attribute name="class">selected</xsl:attribute></xsl:if>
                <a href="{umb:NiceUrl(@id)}">
                    <xsl:value-of select="@nodeName" />
                </a>
    
                <xsl:if test="$childNodes">
                    <ul>
                        <xsl:apply-templates select="$childNodes" />
                    </ul>
                </xsl:if>
            </li>
        </xsl:template>
    
    </xsl:stylesheet>

    /Chriztian

  • BEWD 89 posts 301 karma points
    Aug 01, 2012 @ 00:39
    BEWD
    0

    I apreciate your time on this Chriztian. I did have a sub one working an hour or so ago that would show the next level down i.e on the 'About Us' page it would show Location and Directions. The problem was then when visited one of those pages the navigation would disappear as they had no sub pages.

    I think that all I changed was:

      <!-- Homepage -->
        <xsl:variable name="homeNode" select="$rootNode/Home [@isDoc]" />

    to  

    <!-- Homepage -->
        <xsl:variable name="homeNode" select="$rootNode/About[@isDoc]" />

    and then hid the link to homepage. To make it clear this navigation will not appear on the hompeage as this is controlled by hardcoded links that will not change so at no point does the Home node need to be pointed to.

    Does that make sense?

  • BEWD 89 posts 301 karma points
    Aug 01, 2012 @ 00:42
    BEWD
    0

    Chriztian, that code you posted worked a treat, thank you very much. I will study it not to figure out how it works, it doesnt look that complicated.

    Thank you once again.

  • Chriztian Steinmeier 2798 posts 8788 karma points MVP 7x admin c-trib
    Aug 01, 2012 @ 00:52
    Chriztian Steinmeier
    0

    You're welcome Ben — it's using "match templates" instead of a "for-each" approach. I can only recommend you learn that - it'll get you much neater and maintainable code, especially for navigations, lists etc.

    Maybe check this out: http://pimpmyxslt.com/presentations/2010/xslt-beyond-for-each/

    /Chriztian

     

Please Sign in or register to post replies

Write your reply to:

Draft