Version 6 pre-stable
This version of Silverstripe CMS has not yet been given a stable release. See the release roadmap for more information. Go to documentation for the most recent stable version.

How to create a paginated list

In order to create a paginated list, create a method on your controller that first creates a SS_List that contains all your records (e.g. via the ORM), then wraps it in a PaginatedList object. The PaginatedList constructor should also be passed the HTTPRequest object so it can read the current page information from the ?start= GET var.

The PaginatedList will automatically set up query limits and read the request for information.

// app/src/PageType/MyPageController.php
namespace App\PageType;

use Page;
use PageController;
use SilverStripe\Model\List\PaginatedList;

class MyPageController extends PageController
{
    // ...

    /**
     * Returns a paginated list of all pages in the site.
     */
    public function getPaginatedPages()
    {
        $list = Page::get();

        return PaginatedList::create($list, $this->getRequest());
    }
}

Note that the concept of "pages" used in pagination does not necessarily mean that we're dealing with Page classes, it's just a term to describe a sub-collection of the list.

There are two ways to generate pagination controls: PaginatedList::Pages() and PaginatedList::PaginationSummary(). In this example we will use PaginationSummary().

The first step is to simply list the objects in the template:

<%-- app/templates/App/PageType/Layout/MyPage.ss --%>
<ul>
    <% loop $PaginatedPages %>
        <li><a href="$Link">$Title</a></li>
    <% end_loop %>
</ul>

By default this will display 10 pages at a time. The next step is to add pagination controls below this so the user can switch between pages:

<%-- app/templates/App/PageType/Layout/MyPage.ss --%>
<% if $PaginatedPages.MoreThanOnePage %>
    <% if $PaginatedPages.NotFirstPage %>
        <a class="prev" href="$PaginatedPages.PrevLink">Prev</a>
    <% end_if %>
    <% loop $PaginatedPages.PaginationSummary %>
        <% if $CurrentBool %>
            $PageNum
        <% else %>
            <% if $Link %>
                <a href="$Link">$PageNum</a>
            <% else %>
                ...
            <% end_if %>
        <% end_if %>
    <% end_loop %>
    <% if $PaginatedPages.NotLastPage %>
        <a class="next" href="$PaginatedPages.NextLink">Next</a>
    <% end_if %>
<% end_if %>

If there is more than one page, this block will render a set of pagination controls in the form [1] ... [3] [4] [5] [6] [7] ... [10].

Paginating custom lists

In some situations where you are generating the list yourself, the underlying list will already contain only the items that you wish to display on the current page. In this situation the automatic limiting done by PaginatedList will break the pagination. You can disable automatic limiting using the PaginatedList::setLimitItems() method when using custom lists.

use SilverStripe\Model\List\PaginatedList;

$myPreLimitedList = Page::get()->limit(10, $somePageOffset);

$pages = new PaginatedList($myPreLimitedList, $this->getRequest());
$pages->setLimitItems(false);

Setting the number of items per page

By default, the PaginatedList includes 10 items per page. You can change this by calling setPageLength().

$pages = new PaginatedList(Page::get(), $this->getRequest());
$pages->setPageLength(25);

If you set this limit to 0 it will disable paging entirely, effectively causing it to appear as a single page list.

Template variables

Note that this is not an exhaustive list, as any public method on PaginatedList can be called from the template.

VariableDescription
$MoreThanOnePageReturns true when we have a multi-page list, restricted with a limit.
$NextLink, $PrevLinkLink to the next and previous page of items respectively. They will return blank if there's no appropriate page to go to, so $PrevLink will return blank when you're on the first page.
$FirstLink, $LastLinkLink to the fist and last page of items respectively.
$CurrentPageCurrent page iterated on.
$TotalPagesThe actual (limited) list of records, use in an inner loop
$FirstItemReturns the number of the first item being displayed on the current page. This is useful for things like “displaying 10-20”.
$LastItemReturns the number of the last item being displayed on this page.
$TotalItemsThis returns the total number of items across all pages.
$PagesTotal number of pages.
$PageNumPage number, starting at 1 (within $Pages)
$LinkLinks to the current controller URL, setting this page as current via a GET parameter
$FirstPageReturns true if you're currently on the first page
$LastPageReturns true if you're currently on the last page
$CurrentBoolReturns true if you're currently on that page

API documentation