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"
Comments
define('PAGING_STRING', 'page') seems to break the pagination inside the Dashboard marketplace. I added this to my site.php and then I couldn't turn the page in Dashboard->Extend concrete5->Add-on or Dashboard->Extend concrete5->Themes. It only shows the first 9 items. I have reported it in the Community Leaders forum.
Regards,
Mike
mbt trainers http://www.oakcentre.co.uk
Commenting has been disabled.