The built-in Page List class is one of the most useful tools Concrete5 provides -- almost every site I build uses it in one or two places (at least). The most common use case is when I am building a "recent news" section, which is basically a light-weight blog: you have a page type for "news" or "blog" items, and then one top-level index page which shows the 10 most recent news/blog items.

For simple sites, you can just make a custom template for the built-in Page List block. But I often need additional functionality (like category filters or infinite scrolling), and in these situations I find it much easier to create a single_page with its own controller that I can customize however I see fit.

Using the Page List class itself is rather straightforward:

public function view() {
    $pl = new PageList;
    $pl->sortByPublicDateDescending();
    $pl->filterByCollectionTypeHandle('news');
    $pages = $pl->get();
    $this->set('pages', $pages);
}

This retrieves all pages of the 'news' type, and sorts them with the most-recent first (then sends all of the page/collection objects to the single_page view).

Adding "pagination" functionality is surprisingly easy (although not very intuitive), because the core system handles a lot of the messy work for you. All you need to do is change that page list code to something like this:

public function view() {
    $pl = new PageList;
    $pl->sortByPublicDateDescending();
    $pl->filterByCollectionTypeHandle('news');

    $pl->setItemsPerPage(10);
    $pages = $pl->getPage();
    $this->set('pages', $pages);

    $paginator = $pl->getPagination();
    $this->set('paginator', $paginator);
}

The difference here is that we call setItemsPerPage(), passing in the number of pages we want displayed at a time. Then we call the getPage() method of the page list object instead of just get(). We are also getting the paginator object and passing that to the view -- this lets you easily output the pagination controls ("next", "previous", and the page numbers) like so:

<div class="pagination">
    <span class="pagination-nav"><?php echo $paginator->getPrevious('« Previous'); ?></span>
	<span class="pagination-numbers"><?php echo $paginator->getPages(); ?></span>
	<span class="pagination-nav"><?php echo $paginator->getNext('Next «'); ?></span>
</div>

Pretty URLs

There's one little trick I learned that makes the URL's for the pagination links look cleaner (in my opinion). By default, when a user clicks on the "next" pagination link (or one of the page numbers) then the URL becomes something like http://www.example.com/news?ccm_paging_p=2. I find this to be quite ugly, and prefer to use something simple and more human-readable, like ?page=2. To do so, simply add this line to your site's config/site.php file:

define('PAGING_STRING', 'page'); //override system default of "ccm_paging_p"