Search

I’ve been playing around with a different method to create relative pagination for an entry, adding previous and next links. I was able to use nickdunn’s Order Entries extension to create a “Sort” field and used this field to filter entries. So, I create three data sources, as Allen and Scott had recommended. In this case, I have pages that I have linked to sections using Alistair’s Pages Select Box Field

First, the main entry data source is the Sections entry that corresponds with the $current-page:

Section Data Source

Essentials

  • Name: Section
  • Source: Sections

Filter Results

  • Publish (Checkbox): Value: Yes
  • Page (Page Select Box): Value: {$current-page}

Sorting and Limiting

  • Sort By: System ID
  • Sort Order: descending
  • Show a Maximum of 20 results
  • Show Page 1 of results
  • Required URL Parameter: (none)
  • Redirect to 404 page when no results are found: no

Output Options

  • Parameter Output: Use Field: Sort
  • XML Output: Group By: (None)
  • Included Elements: title, heading, description, body, image, sort

This data source outputs a data source parameter, $ds-section, that I can use in my “Previous Section” and “Next Section” data sources to tell MySQL to filter by different ranges:

Previous Section Data Source

Essentials

  • Name: Previous Section
  • Source: Sections

Filter Results

  • Publish (Checkbox): Value: Yes
  • Sort (Entry Order): Value: mysql: value < {$ds-section}

Sorting and Limiting

  • Sort By: Sort
  • Sort Order: descending
  • Show a Maximum of 1 results
  • Show Page 1 of results
  • Required URL Parameter: (none)
  • Redirect to 404 page when no results are found: no

Output Options

  • Parameter Output: Use Field: (None)
  • XML Output: Group By: (None)
  • Included Elements: title, page, sort

And the “Next Section” data source:

Next Section Data Source

Essentials

  • Name: Next Section
  • Source: Sections

Filter Results

  • Publish (Checkbox): Value: Yes
  • Sort (Entry Order): Value: mysql: value > {$ds-section}

Sorting and Limiting

  • Sort By: Sort
  • Sort Order: ascending
  • Show a Maximum of 1 results
  • Show Page 1 of results
  • Required URL Parameter: (none)
  • Redirect to 404 page when no results are found: no

Output Options

  • Parameter Output: Use Field: (None)
  • XML Output: Group By: (None)
  • Included Elements: title, page, sort

This is great, because it gives me the following XML:

<section>
    <section id="2" handle="sections">Sections</section>
    <entry id="33" entries="0">
        <title handle="imagine">Imagine</title>
        <heading handle="imagine-something-better">Imagine something better</heading>
        <description word-count="78"><p>It starts with an idea to meet a need, to solve a problem, to overcome a challenge, to improve upon the status quo, to reach beyond the ordinary, to realize a dream. Then comes the part where the world of ideas meets everyday life. All these ideas we have are very abstract and subjective. How can we bring these ideas into reality and accomplish these goals and objectives in the real world? Here is where design can help.</p></description>
        <body word-count="0" />
        <sort>7</sort>
        <image>
            <item handle="the-elementary-forms-sphere" id="16">The Elementary Forms - Sphere</item>
        </image>
    </entry>
</section>
<next-section>
    <section id="2" handle="sections">Sections</section>
    <entry id="36" entries="0">
        <title handle="resources">Resources</title>
        <page>
            <page handle="resources" id="19">Resources</page>
        </page>
        <sort>8</sort>
    </entry>
</next-section>
<previous-section>
    <section id="2" handle="sections">Sections</section>
    <entry id="31" entries="0">
        <title handle="contact">Contact</title>
        <page>
            <page handle="contact" id="7">Contact</page>
        </page>
        <sort>6</sort>
    </entry>
</previous-section>

The Pages Field extension outputs page IDs in the XML. I discovered, however, that the Navigation data source does not output IDs. So, if there are any pages that have the same name, they cannot be matched properly. A fix can be easily produced for this, but I’m not sure whether this should be made as a change to the core file, or as an extension. If it should be made as an extension, does anyone have an example of a data source extension? I suppose I could use the Google Custom Search Engine Data Source extension as a model for extending the Datasource class.

Edit: Updated with the correct sort by field and sort order.

This is actually working really well. I’ve only got it figured out to two levels of page hierarchy, but you can probably figure out how to go deeper with the following code:

<xsl:template name="previous-next-links">
    <xsl:param name="previous-page-id" select="/data/previous-section/entry/page/page/@id" />
    <xsl:param name="next-page-id" select="/data/next-section/entry/page/page/@id" />
    <li class="right">
        <xsl:apply-templates select="/data/navigation/page[@id = $next-page-id]" mode="previous-next">
            <xsl:with-param name="title" select="'Next'"/>
        </xsl:apply-templates>
        <xsl:apply-templates select="/data/navigation/page/page[@id = $next-page-id]" mode="previous-next">
            <xsl:with-param name="title" select="'Next'"/>
        </xsl:apply-templates>
    </li>
    <li class="right">
        <xsl:apply-templates select="/data/navigation/page[@id = $previous-page-id]" mode="previous-next">
            <xsl:with-param name="title" select="'Previous'"/>
        </xsl:apply-templates>
        <xsl:apply-templates select="/data/navigation/page/page[@id = $previous-page-id]" mode="previous-next">
            <xsl:with-param name="title" select="'Previous'"/>
        </xsl:apply-templates>
    </li>
</xsl:template>

<xsl:template match="/data/navigation/page" mode="previous-next">
    <xsl:param name="title" select="''" />
    <a href="{$root}/{@handle}/">
        <xsl:value-of select="$title"/>
    </a>
</xsl:template>

<xsl:template match="/data/navigation/page/page" mode="previous-next">
    <xsl:param name="title" select="''" />
    <a href="{$root}/{../@handle}/{@handle}/">
        <xsl:value-of select="$title"/>
    </a>
</xsl:template>

Edit: Simplified to be more flexible by using a single $title parameter.

Bauhouse thanks for this! I’ve added this to the growing list here.

While this seems to be the cleanest method yet, there is still one problem. The valuable Output Parameter for that Data Source is stolen for pagination. A lot of the time we’ll have Images or Comments attached to a main entry like this and need to use the Output Parameter as System ID.

To get around this you could simply create the main Data Source again as a duplicate — the same filters but different Output Params (and only one needs to output XML since they’re identical). It’s extra queries, but gets us the two parameters.

Yes, Nick, there is that issue. Thanks so much for the Order Entries field. Works beautifully.

Create an account or sign in to comment.

Symphony • Open Source XSLT CMS

Server Requirements

  • PHP 5.3-5.6 or 7.0-7.3
  • PHP's LibXML module, with the XSLT extension enabled (--with-xsl)
  • MySQL 5.5 or above
  • An Apache or Litespeed webserver
  • Apache's mod_rewrite module or equivalent

Compatible Hosts

Sign in

Login details