Copied to clipboard

Flag this post as spam?

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


  • Dan 1288 posts 3921 karma points 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 535 posts 980 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 4026 posts 15836 karma points MVP 13x 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 4026 posts 15836 karma points MVP 13x admin c-trib
    Nov 18, 2009 @ 14:59
    Lee Kelleher
    0

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

  • Dan 1288 posts 3921 karma points 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.

Please Sign in or register to post replies

Write your reply to:

Draft