Copied to clipboard

Flag this post as spam?

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


  • Garrett Fisher 341 posts 496 karma points
    Feb 12, 2010 @ 18:01
    Garrett Fisher
    0

    previous page, next page

    Hi,

    I'd like to create come controls to navigate among sibling pages on my site.  Actually, though, they're not direct siblings, it's a little tricky.  Here's the structure:

    2009
    - Item 1
    - Item 2
    - Item 3

    2008
    - Item 1
    - Item 2
    - Item 3
    2007
    - Item 1
    - Item 2
    - Item 3

    ...etc. I want to navigate, back and forward, among thse "Item" nodes.  I CAN start with the parent node of the 2009, 2008, etc. and then check for a nodeTypeAlias, just FYI.  I see basically how to select the right collection of nodes, I just don't know how to get the "Next" and "Previous" links.  Can anyone offer some XSLT help with this?

    Thanks,

    Garrett

     

  • Nik Wahlberg 639 posts 1237 karma points MVP
    Feb 12, 2010 @ 19:35
    Nik Wahlberg
    3

    Assuming you can get your nodesets together by creating one or multiple xpath statements, this should get you going with the paging. I've used this as an example in the past and it works a charm! 

    http://www.nibble.be/?p=11

    Hth,
    Nik

  • Petr Snobelt 923 posts 1535 karma points
    Feb 12, 2010 @ 23:41
    Petr Snobelt
    0

    I recommend this article, specially my addition :-)

    http://www.nibble.be/?p=44

    Petr

  • Garrett Fisher 341 posts 496 karma points
    Feb 16, 2010 @ 15:47
    Garrett Fisher
    0

    Hello Petr, Nik-- thanks so much for the replies.

    The code on Page 11 that Nik pointed me to  showed the Prev and Next links but every link was to the same page that I was on.

    Petr's code using preceding-sibling and following-sibling won't work for me because of the structure of my site (indicated in the first post)-- all the news items are not siblings of each other because of the individual year holder objects shown in my first post. I will need to use a for-each loop.

    So, that relegates me to the following code:

    <?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"
    exclude-result-prefixes="msxml umbraco.library">

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

    <xsl:param name="currentPage"/>

    <xsl:template match="/">

    <!-- The fun starts here -->

    <xsl:for-each select="$currentPage/ancestor-or-self::node [@nodeTypeAlias = 'CWS_NewsItem']/node">

    <xsl:if test="$currentPage/@id = current()/@id">

    <xsl:call-template name="prevnext">

    <xsl:with-param name="count" select="count($currentPage/ancestor-or-self::node [@nodeTypeAlias = 'CWS_NewsItem']/node)"/>
    <xsl:with-param name="itemindex" select="position()"/>

    </xsl:call-template>

    </xsl:if>

    </xsl:for-each>

    </xsl:template>


    <xsl:template name="prevnext" >

    <xsl:param name="count" />
    <xsl:param name="itemindex" />

    <xsl:if test="$itemindex &gt; 1">

    <a href="{umbraco.library:NiceUrl($currentPage/ancestor-or-self::node [@nodeTypeAlias = 'CWS_NewsItem']/node[$itemindex - 1]/@id)}">Previous</a>

    </xsl:if>

    <xsl:if test="$itemindex &lt; $count">

    <a href="{umbraco.library:NiceUrl($currentPage/ancestor-or-self::node [@nodeTypeAlias = 'CWS_NewsItem']/node[$itemindex + 1]/@id)}">Next</a>

    </xsl:if>

    </xsl:template>

    </xsl:stylesheet>

    However, the links are not showing up.  Can anyone offer any advice as to why this isn't working?

    Thanks again and in advance,

    Garrett

  • Chriztian Steinmeier 2800 posts 8790 karma points MVP 8x admin c-trib
    Feb 17, 2010 @ 00:43
    Chriztian Steinmeier
    0

    Hi Garrett,

    There's two tricks involved in solving this one: The node-set() function and the xsl:number instruction.

    The node-set() function (available in the 'MSXML' namespace or in the Exslt 'Common' namespace) will collect the nodes into a single set, so that it's possible to say "Give me the 5th node in this set" and actually get the 2nd node of the 2nd "group" (following your sample data).

    Since the preceding-sibling and following-sibling axes, along with the position() function, only operate on the original source tree, we'll need to find some alternative way to get the info they provide.

    I generally like to keep the output code as clean as possible, so I'm performing the bulk of the logic in setting up a couple of variables for use in the output, so the actual output is easily understood.

    Here's the code:

    <?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"
        xmlns:msxml="urn:schemas-microsoft-com:xslt"
        exclude-result-prefixes="umbraco.library msxml"
    >
    
        <xsl:output method="xml" indent="yes" omit-xml-declaration="yes" />
    
        <xsl:param name="currentPage" />
    
        <!--
            Grab the root of the site (assumes first level is actual root, e.g. for multi-language sites, otherwise,
            use "$currentPage/ancestor-or-self::root" to grab the absolute root)
        -->
        <xsl:variable name="siteRoot" select="$currentPage/ancestor-or-self::node[@level = 1]" />
    
        <!-- Alias of the grouping nodes (e.g. the "2009" holder node in an archive structure) -->
        <xsl:variable name="groupType" select="'CWS_NewsItem'" />
    
        <!-- Create a special collection of nodes for paging -->
        <xsl:variable name="data" select="msxml:node-set($siteRoot/node[@nodeTypeAlias = $groupType]/node)" />
    
        <xsl:template match="/">
            <xsl:apply-templates select="$currentPage" />
        </xsl:template>
    
        <xsl:template match="node">
            <!-- Find the equivalent of position() but within our special collection -->
            <xsl:variable name="p">
                <xsl:number level="any" count="node[@nodeTypeAlias = $groupType]/node" />
            </xsl:variable>
    
            <xsl:variable name="prevNodeId">
                <xsl:choose>
                    <xsl:when test="$currentPage/@id = $data[1]/@id">
                        <xsl:value-of select="$data[last()]/@id" />
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:value-of select="$data[$p - 1]/@id" />
                    </xsl:otherwise>
                </xsl:choose>
            </xsl:variable>
            <xsl:variable name="nextNodeId">
                <xsl:choose>
                    <xsl:when test="$currentPage/@id = $data[last()]/@id">
                        <xsl:value-of select="$data[1]/@id" />
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:value-of select="$data[$p + 1]/@id" />
                    </xsl:otherwise>
                </xsl:choose>
            </xsl:variable>
    
            <!-- Output the links -->
            <a href="{umbraco.library:NiceUrl($prevNodeId)}" rel="pre">Previous</a> | <a href="{umbraco.library:NiceUrl($nextNodeId)}" rel="next">Next</a>
    
        </xsl:template>
    
    </xsl:stylesheet>

    This version also enables wrapping from the last item to the first and vice versa - should be fairly easy to see where that is done if you want to disable that.

    You may need to change the variable 'groupType' and you'll most likely have to change the XPath in the 'data' variable if you have additional levels of nodes before the structure you are processing. When changing the XPath for the data variable, remember to keep the "count" attribute of the xsl:number instruction in sync with it...

    Hope this helps,

    /Chriztian

  • Matt Taylor 873 posts 2086 karma points
    Jan 17, 2011 @ 12:29
    Matt Taylor
    0

    I've use Petr's contribution to the following http://www.nibble.be/?p=44 in version 4 of Umbraco but it doesn't seem to be working for me in a 4.5 installation?

    Is there a reason for this or am I being dumb?

    Regards,

    Matt

  • Matt Taylor 873 posts 2086 karma points
    Jan 18, 2011 @ 14:33
    Matt Taylor
    0

    Can anybody help me with this?

    Not working in my 4.5.2 project.

    <xsl:template match="/">

      <xsl:if test="count($currentPage/preceding-sibling::node) != 0">

          <a href="{umbraco.library:NiceUrl($currentPage/preceding-sibling::node[1]/@id)}">
            Previous
          </a>
          <br />
        </xsl:if>

        <xsl:if test="count($currentPage/following-sibling::node) != 0">
          <a href="{umbraco.library:NiceUrl($currentPage/following-sibling::node[1]/@id)}">
            Next
          </a>
        </xsl:if>

    </xsl:template>
  • Matt Taylor 873 posts 2086 karma points
    Jan 18, 2011 @ 14:50
    Matt Taylor
    0

    Scrabbled around the forum and found that 'node' needs to be changed to *[@isDoc]

    Easy if you know how, but where do you find out this kind of stuff?

  • Jan Skovgaard 11280 posts 23678 karma points MVP 11x admin c-trib
    Jan 18, 2011 @ 21:23
    Jan Skovgaard
    2

    Hi Matt

    That's because the example you posted used the legacy XML schema. With version 4.5 the XML schema changed. So therefore there are many XSLT examples based on the legacy schema around the forum and elsewhere.

    However there are some wiki entries about it and it's possible to make Umbraco use the legacy schema by changing it in the UmbracoSettings.config file.

    I like this entry by Sebastian Janssen: http://our.umbraco.org/wiki/reference/xslt/45-xml-schema/switching-between-old-and-new-schema

    Lee Kelleher has also written this blogpost just before the release of 4.5 (hence the reference for 4.1, which was the version people were expecting untill the 4.5 surprise at codegarden) http://blog.leekelleher.com/2010/04/02/working-with-xslt-using-new-xml-schema-in-umbraco-4-1/

    However I agree with you that for people new to Umbraco and the use of XSLT in Umbraco this can be rather confusing. But hey, that's why we are in here to help each other out with questions like these :-)

    Hope this answer is usefull to you.

    /Jan

  • Matt Taylor 873 posts 2086 karma points
    Jan 19, 2011 @ 10:30
    Matt Taylor
    0

    Thanks for reply and the information.

    The blog post was useful to read as I've certainly been strggling to figure out what changes to make when converting old to new schemas.

    Regards,

    Matt

     

Please Sign in or register to post replies

Write your reply to:

Draft