Copied to clipboard

Flag this post as spam?

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


  • Alex Burr 77 posts 128 karma points
    Mar 10, 2011 @ 18:49
    Alex Burr
    0

    Here we go again... subnavigation in XSLT

    Here is my content node tree:

    The site root "The Patient Experience" will have no left hand navigation, but first-level sub-pages beneath it will. Right now the only sub-page is "Patient and Family Centered Care", but there will be others.

    So here's what I'd like to do. Each page that is one level below the root should include a left hand navigation that shows itself plus its children in a single-level list. Therefore once a visitor clicks on "Patient and Family-Centered Care", from the root, the subnav markup should be:

    <ul id="contextNav">
      <li><a href="/patient-and-family-centered-care/" class="currentPage">Patient and Family Centered Care</a></li>
      <li><a href="/patient-and-family-centered-care/smh-mission-and-vision.aspx">SMH Mission and Vision</a></li>
      <li><a href="/patient-and-family-centered-care/our-principles-of-patient-and-family-centered-care.aspx">Our Principles of Patient- and Family-Centered Care</a></li>
    </ul>

    Once a visitor clicks on "SMH Mission and Vision" the markup should be:

    <ul id="contextNav">
        <li><a href="/patient-and-family-centered-care/">Patient and Family Centered Care</a></li>
        <li><a href="/patient-and-family-centered-care/smh-mission-and-vision.aspx" class="currentPage">SMH Mission and Vision</a></li>
        <li><a href="/patient-and-family-centered-care/our-principles-of-patient-and-family-centered-care.aspx">Our Principles of Patient- and Family-Centered Care</a></li>
    </ul>

    Please note that I do NOT want this...

    <ul id="contextNav">
        <li><a href="/patient-and-family-centered-care/">Patient and Family Centered Care</a>
            <ul>
                <li><a href="/patient-and-family-centered-care/smh-mission-and-vision.aspx" class="currentPage">SMH Mission and Vision</a></li>
                <li><a href="/patient-and-family-centered-care/our-principles-of-patient-and-family-centered-care.aspx">Our Principles of Patient- and Family-Centered Care</a></li>
            </ul>
        </li> 
    </ul>

    So here's my XSL, which is basically the default helper XSL:

    <xsl:variable name="level" select="2"/>
    
    <xsl:template match="/">
    
      <!-- The fun starts here -->
      <ul id="contextNav">
        <!-- Home node added here -->
          <li>
        <a href="/">Home</a>
          </li>
        <!-- Loop through site -->
        <xsl:for-each select="$currentPage/ancestor-or-self::* [@isDoc and @level=$level]/* [@isDoc and string(umbracoNaviHide) != '1']">
          <li>
            <a href="{umbraco.library:NiceUrl(@id)}">
              <xsl:if test="$currentPage/ancestor-or-self::*/@id = current()/@id">
                <!-- we're under the item - you can do your own styling here -->
                <xsl:attribute name="class">currentPage</xsl:attribute>
              </xsl:if>
              <xsl:value-of select="@nodeName"/>
            </a>
          </li>
        </xsl:for-each>
      </ul>
    
    </xsl:template>

    I hope someone can help me with what I'm trying to do here. XSL is confusing as heck to me and the Umbraco schema doesn't make it any easier. 

  • Tom Fulton 2030 posts 4998 karma points c-trib
    Mar 10, 2011 @ 19:00
    Tom Fulton
    0

    Hi,

    I would probably do something like this:

    <xsl:variable name="level" select="2"/>


    <xsl:variable name="startNode" select="currentPage/ancestor-or-self::* [@isDoc][@level=$level]"/>

    <ul>
    <!-- write out the parent link manually -->
    <li><a href="{umbraco.library:NiceUrl($startNode/@id)}"><xsl:value-of select="$startNode/@nodeName"/></a></li>

    <!-- write out the sibling links as normal -->
    <xsl:for-each select="$startNode/* [@isDoc]">
    <li>
    <a href="{umbraco.library:NiceUrl(@id)}">
    <xsl:if test="$currentPage/ancestor-or-self::*/@id = current()/@id">
    <!-- we're under the item - you can do your own styling here -->
    <xsl:attribute name="class">currentPage</xsl:attribute>
    </xsl:if>
    <xsl:value-of select="@nodeName"/>
    </a>
    </li>
    </xsl:for-each>
    </ul>

    -Tom

  • Alex Burr 77 posts 128 karma points
    Mar 10, 2011 @ 20:41
    Alex Burr
    0

    Hmmm...

    That gave me this dreaded error:

    System.OverflowException: Value was either too large or too small for an Int32. 
    at System.Convert.ToInt32(Double value) 
    at System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider) 
    at System.Xml.Xsl.Runtime.XmlQueryRuntime.ChangeTypeXsltArgument(XmlQueryType xmlType, Object value, Type destinationType) 
    at System.Xml.Xsl.Runtime.XmlQueryContext.InvokeXsltLateBoundFunction(String name, String namespaceUri, IList`1[] args) 
    at (XmlQueryRuntime {urn:schemas-microsoft-com:xslt-debug}runtime) 
    at Root(XmlQueryRuntime {urn:schemas-microsoft-com:xslt-debug}runtime) 
    at System.Xml.Xsl.XmlILCommand.Execute(Object defaultDocument, XmlResolver dataSources, XsltArgumentList argumentList, XmlWriter writer) 
    at System.Xml.Xsl.XslCompiledTransform.Transform(IXPathNavigable input, XsltArgumentList arguments, TextWriter results) 
    at umbraco.presentation.webservices.codeEditorSave.SaveXslt(String fileName, String oldName, String fileContents, Boolean ignoreDebugging)
    
    

     

     

  • Jan Skovgaard 11280 posts 23678 karma points MVP 10x admin c-trib
    Mar 10, 2011 @ 21:08
    Jan Skovgaard
    0

    Hi Alex

    Try checking the "skip error checking" - it's because the XSLT processor does not know the value if the id before runtime probably.

    Hope this helps.

    /Jan

  • Chriztian Steinmeier 2798 posts 8788 karma points MVP 7x admin c-trib
    Mar 10, 2011 @ 21:22
    Chriztian Steinmeier
    2

    Hi Alex,

    Try this set of templates and tweak to your liking:

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

    /Chriztian

  • Tom Fulton 2030 posts 4998 karma points c-trib
    Mar 10, 2011 @ 21:24
    Tom Fulton
    1

    I keep telling myself I'm going to learn to use templates properly someday... :)

  • Chriztian Steinmeier 2798 posts 8788 karma points MVP 7x admin c-trib
    Mar 10, 2011 @ 21:38
    Chriztian Steinmeier
    0

    @Tom: You'll like 'em :-) They're what XSLT is all about. Really :-)

    /Chriztian

  • Alex Burr 77 posts 128 karma points
    Mar 10, 2011 @ 22:33
    Alex Burr
    0

    Chriztian,

    You solved it for me. Thank you so much!

Please Sign in or register to post replies

Write your reply to:

Draft