Copied to clipboard

Flag this post as spam?

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


  • Dan 1250 posts 3747 karma points admin c-trib
    Nov 18, 2009 @ 14:35
    Dan
    0

    XSLT navigation not closing properly

    Hi,

    I've got a macro which lists all level 2 navigation on a page.  Here's the XSLT:

    <?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:msxml="urn:schemas-microsoft-com:xslt"
        xmlns:umbraco.library="urn:umbraco.library" xmlns:Exslt.ExsltCommon="urn:Exslt.ExsltCommon" xmlns:Exslt.ExsltDatesAndTimes="urn:Exslt.ExsltDatesAndTimes" xmlns:Exslt.ExsltMath="urn:Exslt.ExsltMath" xmlns:Exslt.ExsltRegularExpressions="urn:Exslt.ExsltRegularExpressions" xmlns:Exslt.ExsltStrings="urn:Exslt.ExsltStrings" xmlns:Exslt.ExsltSets="urn:Exslt.ExsltSets"
        exclude-result-prefixes="msxml umbraco.library Exslt.ExsltCommon Exslt.ExsltDatesAndTimes Exslt.ExsltMath Exslt.ExsltRegularExpressions Exslt.ExsltStrings Exslt.ExsltSets ">

    <xsl:output method="xml" omit-xml-declaration="yes"/>

    <xsl:param name="currentPage"/>

    <xsl:template match="/">

    <ul id="page-nav">
    <xsl:for-each select="$currentPage/node [string(data [@alias='umbracoNaviHide']) != '1']">
        <li>
            <a href="{umbraco.library:NiceUrl(@id)}">
                <xsl:value-of select="@nodeName"/>
            </a>
        </li>
    </xsl:for-each>
    </ul>

    </xsl:template>

    </xsl:stylesheet>

      However, sometimes there isn't any level 2 navigation for the page.  When this happens, the above macro renders an opening list tag (<ul id="page-nav">) but doesn't close it.  It somehow doesn't recognise that there's a </ul> at the end.  So this breaks my HTML and the layout goes wrong.

    Can anyone see how to fix this, or even check that there are items there before writing out the opening list tag?

    Thanks folks...

  • Chris Houston 533 posts 977 karma points MVP admin c-trib
    Nov 18, 2009 @ 14:54
    Chris Houston
    2

    Hi Dan,

    Just wrap your UL section in an XSL:IF statement:

    <?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:msxml="urn:schemas-microsoft-com:xslt"
       
    xmlns:umbraco.library="urn:umbraco.library" xmlns:Exslt.ExsltCommon="urn:Exslt.ExsltCommon" xmlns:Exslt.ExsltDatesAndTimes="urn:Exslt.ExsltDatesAndTimes" xmlns:Exslt.ExsltMath="urn:Exslt.ExsltMath" xmlns:Exslt.ExsltRegularExpressions="urn:Exslt.ExsltRegularExpressions" xmlns:Exslt.ExsltStrings="urn:Exslt.ExsltStrings" xmlns:Exslt.ExsltSets="urn:Exslt.ExsltSets"
       
    exclude-result-prefixes="msxml umbraco.library Exslt.ExsltCommon Exslt.ExsltDatesAndTimes Exslt.ExsltMath Exslt.ExsltRegularExpressions Exslt.ExsltStrings Exslt.ExsltSets ">

    <xsl:output method="xml" omit-xml-declaration="yes"/>

    <xsl:param name="currentPage"/>

    <xsl:template match="/">

    <xsl:if test="count(
    $currentPage/node [string(data [@alias='umbracoNaviHide']) != '1']) &gt; 0">

    <ul
    id="page-nav">
    <xsl:for-each select="$currentPage/node [string(data [@alias='umbracoNaviHide']) != '1']">
       
    <li>
           
    <a href="{umbraco.library:NiceUrl(@id)}">
               
    <xsl:value-of select="@nodeName"/>
           
    </a>
       
    </li>
    </xsl:for-each>
    </ul>

    </xsl:if>

    </xsl:template>

    </xsl:stylesheet>

    Cheers,

    Chris

  • Lee Kelleher 3945 posts 15163 karma points MVP 10x admin c-trib
    Nov 18, 2009 @ 14:58
    Lee Kelleher
    1

    Hi Dan,

    You've got 2 options...

    1. Change the output method to HTML:

    <xsl:output method="html" omit-xml-declaration="yes" />

    This will leave you with <ul id="page-nav"></ul> - which you may or may not want.

    2. Put an IF condition around the <ul> tags:

    <xsl:template match="/">
        <xsl:if test="count($currentPage/node[string(data[@alias='umbracoNaviHide']) != '1']) &gt; 0">
            <ul id="page-nav">
                <xsl:for-each select="$currentPage/node[string(data[@alias='umbracoNaviHide']) != '1']">
                    <li>
                        <a href="{umbraco.library:NiceUrl(@id)}">
                            <xsl:value-of select="@nodeName"/>
                        </a>
                    </li>
                </xsl:for-each>
            </ul>
        </xsl:if>
    </xsl:template>

    So if there are no nodes to display, then it wont output the <ul> tags.  Personally I'd extend this so that the "$currentPage/node[string(data[@alias='umbracoNaviHide']) != '1']" is in an xsl:variable - saves calling the same XPath twice!

    Cheers, Lee.

  • Lee Kelleher 3945 posts 15163 karma points MVP 10x admin c-trib
    Nov 18, 2009 @ 14:59
    Lee Kelleher
    0

    @Chris ... cross-posted at the same time!  Great minds think alike! :-)

  • Dan 1250 posts 3747 karma points admin c-trib
    Nov 18, 2009 @ 15:19
    Dan
    0

    Thanks both, the 'if' thing works a treat.  No empty list too, so it's the prefered option.

  • 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