Copied to clipboard

Flag this post as spam?

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


  • Eddie Foreman 215 posts 288 karma points
    Aug 21, 2010 @ 00:36
    Eddie Foreman
    0

    Hide Parent UL

    Hi All

    The following xslt hides and shows nested UI, from a certain level. Including the parent ul. The xslt was taken from another topic, and I've tweak (slighty) to get me this far.

    Example html:

        <ul>
    <li><a href="/about.aspx">About Us</a>
    <ul>
    <li><a href="/about/people.aspx">People</a>
    <ul>
    <li>...</li>
    </ul>
    </li>
    <li><a href="/about/history.aspx">Philosophy</a>
    <ul>
    <li>...</li>
    </ul>
    </li>
    </ul>
    </li>
    </ul>

    Looking to get this:

                <ul>
    <li><a href="/about/people.aspx">People</a>
    <ul>
    <li>...</li>
    </ul>
    </li>
    <li><a href="/about/history.aspx">Philosophy</a>
    <ul>
    <li>...</li>
    </ul>
    </li>
    </ul>

    Macro:

    <?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:ms="urn:schemas-microsoft-com:xslt"
    xmlns:umb="urn:umbraco.library"
    exclude-result-prefixes="ms umb">

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

    <xsl:param name="currentPage" />
    <xsl:param name="root" select="$currentPage/ancestor-or-self::root" />
    <xsl:variable name="level" select="2" />

    <xsl:template match="/">
    <ul>
    <xsl:apply-templates select="$currentPage/ancestor-or-self::node [@level = $level]" />
    </ul>
    </xsl:template>

    <xsl:template match="node">
    <li>
    <xsl:if test="$currentPage/@id = current()/@id">
    <xsl:attribute name="class">current</xsl:attribute>
    </xsl:if>
    <a href="{umb:NiceUrl(@id)}">
    <xsl:value-of select="@nodeName"/>
    </a>
    <!-- Continue down this branch? -->
    <xsl:if test="descendant-or-self::node = $currentPage and node[data[@alias = 'umbracoNaviHide'] = 0]">
    <ul>
    <xsl:apply-templates select="node" />
    </ul>
    </xsl:if>
    </li>
    </xsl:template>

    <!-- Handle nodes explicitly hidden from navigation -->
    <xsl:template match="node[data[@alias = 'umbracoNaviHide'] = 1]" />


    </xsl:stylesheet>

    If possible I would like to remove the current parent UL, but when I try none of the menu is displayed.  I feel I may need to introduce additonal templates?

    Thanks in advance

    Eddie

  • Sascha Wolter 615 posts 1101 karma points
    Aug 21, 2010 @ 02:40
    Sascha Wolter
    0

    Hi Eddie,

    what if you remove the recursive call from the match="node" template (aka get rid of this bit:

          <!-- Continue down this branch? -->
         
    <xsl:if test="descendant-or-self::node = $currentPage and node[data[@alias = 'umbracoNaviHide'] = 0]">
           
    <ul>
             
    <xsl:apply-templates select="node" />
           
    </ul>
         
    </xsl:if>

    and start the call one level deeper or at a specific node? Not sure if I understand you correctly though.

    Sascha

     

  • Eddie Foreman 215 posts 288 karma points
    Aug 21, 2010 @ 12:30
    Eddie Foreman
    0

    Hi Sascha

    Unfortunately removing that section gives the opposite effect and produces:

    <ul>
    <li class="current">
    <a href="/about.aspx">About Us</a>
    </li>
    </ul>

    It looks like I need to retain this part, and possibly call a second template. The following XSLT produces the correct mark-up:

      <xsl:param name="currentPage"/>

    <xsl:template match="/">
    <xsl:call-template name="construct">
    <xsl:with-param name="node" select="$currentPage/ancestor-or-self::node [@level = 2]"/>
    </xsl:call-template>
    </xsl:template>

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

    </xsl:stylesheet>

    But I cannot work out how to get this to only show the child menu items related the current page.  So when people is the current page, the menu would look like this:

                <ul>
                   
    <li><a href="/about/people.aspx">People</a>
                       
    <ul>
                           
    <li>...</li>
                            <li>...</li>
                        </ul>
                   
    </li>
                   
    <li><a href="/about/history.aspx">Philosophy</a></li>
               
    </ul>

    Or when History is the current page then the menu would look like:

                <ul>
    <li><a href="/about/people.aspx">People</a></li>
    <li><a href="/about/history.aspx">History</a>
    <ul>
    <li>...</li>
    <li>...</li>
    </ul>
    </li>
    </ul>

    Ideally I need the mark-up form the xslt in this thread, but with the show/hide effect produced from by the xslt in the opening message.

    Any ideas on how to achive this?

    Thanks again

    Eddie

  • Sascha Wolter 615 posts 1101 karma points
    Aug 22, 2010 @ 11:32
    Sascha Wolter
    0

    Hi Eddie,

    I think I understand it now. Basically the items at the first level will always be the same, e.g.

    people
    history
    something else
    ...

    but you only want the sub tree to expand for the page people are currently on, so if I'm on the history page I'll get

    people
    history
    - founding fathers
    - first steps
    - ...
    something else
    ...

    You should be able to achieve that by extending the if test before you call the sub nodes, so instead of

    <xsl:if test="count(./node) &gt; 0">

    do something like

    <xsl:if test="count(./node) &gt; 0 and ./@id = $currentPage/@id">

    So basically build the child nodes if
    - there are any and
    - the id of the first level node the loop is currently processing is identical to the id of the current page.

    Hope it works,
    Sascha

  • Eddie Foreman 215 posts 288 karma points
    Aug 22, 2010 @ 21:02
    Eddie Foreman
    0

    Hi Sascha

    It almost works, the correct sub pages are shown when clicking on history.  But when I then click on say founding fathers, it only shows people and history.  When I need to show:

    history
    - founding fathers
      -plus any child pages
    - first steps

    I had a similar thinking to you, where I would add a count and when greater then 0, create the menu.  But I was thinking of using it with the xslt at the beginning of the thread.  But to date, have not got it to work.  Will keep trying.

    Thanks again for you help.

    Eddie

Please Sign in or register to post replies

Write your reply to:

Draft