Skeleton Framework: Pagination Component - Please Review
Posted: Fri May 29, 2009 1:29 am
Arborint and I have been hard at work on a pagination component that can be used standalone or as part of the Skeleton framework. We're looking for feedback from the DevNetwork community, so take a look and let us know what you think.
Executive Summary
We made these classes first and foremost to make it drop-dead easy to paginate data. Our goal was not to make a one size fits all solution, but rather to provide a layered range of solutions in which developers can pick and choose to tailor the classes to their needs.
Specific Goals
The base object in this pagination system is a Value Object that holds the values for the list and does the necessary calculations. This class can be used alone, but you are required to initialize it.
This component also provides a class that extends the Core class and initializes itself from the request so you don't have to. This class adds a process() method that will initialize the object for you:
This Core object does the necessary calculation and will return page numbers for the current first, last, next and previous pages, plus a range of page numbers around the current page. These are intended to provide the basic functionality on which to build classes to render paginated output.
This class takes a Datasource object passed to the constructor. These Datasources comply to a simple Adapter interface. This component will provide Adapters for arrays, PDO, MySQL, etc. A getItems() method is provided to retrieve the records for the currently displayed page.
The basic methods in its interface are:
This component is not monolithic. There are several levels of classes that use a Core object and provide support for rendering output. The lowest level of output support uses page numbers from a Core object and builds URLs. Using this class you can have complete control of your template:
The next level of output support uses page numbers from a Core object and builds complete links (<a> tags). You an pass the name of a CSS class to this object to control link style:
Use Case Example
Here is an example of combining the classes to do a basic paginated list with links:
Additional Features
For the most automated use case, we will be providing a DataGrid that takes care of all HTML once the core classes have been finalized.
The code attachment is an older version
Latest code available at: http://skeleton.googlecode.com/
Executive Summary
We made these classes first and foremost to make it drop-dead easy to paginate data. Our goal was not to make a one size fits all solution, but rather to provide a layered range of solutions in which developers can pick and choose to tailor the classes to their needs.
Specific Goals
- Account for as many use cases as possible
- Stay flexible for extendability
- Take care of the messy details of pagination: url generation, maintaining state, dealing with the request.
The base object in this pagination system is a Value Object that holds the values for the list and does the necessary calculations. This class can be used alone, but you are required to initialize it.
Code: Select all
$pager = new A_Pagination_Core($datasource);
$pager->setCurrentPage(intval($_GET['mypagevar']));
$pager->setNumItems(intval($_GET['mycountvar']));Code: Select all
$pager = new A_Pagination_Request($datasource);
$pager->process();This class takes a Datasource object passed to the constructor. These Datasources comply to a simple Adapter interface. This component will provide Adapters for arrays, PDO, MySQL, etc. A getItems() method is provided to retrieve the records for the currently displayed page.
The basic methods in its interface are:
Code: Select all
class A_Pagination_Core {
function __construct($datasource)
function isPage($number)
function getPage($number)
function getCurrentPage()
function getFirstPage()
function getLastPage()
function getPageRange()
function getNumItems()
function getItems()
}Code: Select all
$url = new A_Pagination_Helper_Url($pager);
$out .= '<a href="' . $url->previous() . '">Prev</> ";
$out .= '<a href="' . $url->next('Next') . '">Next</> ";Code: Select all
$url = new A_Pagination_Helper_Link($pager);
$out .= $link->previous('Prev', 'mylinkclass');
$out .= $link->next('Next', 'mylinkclass');Here is an example of combining the classes to do a basic paginated list with links:
Code: Select all
// create a data object that has the interface needed by the Pager object
$datasource = new Datasource();
// create a request processor to set pager from GET parameters
$pager = new A_Pagination_Request($datasource);
// initialize using values from $_GET
$pager->process();
// create a "standard" view object to create pagination links
include 'A/Pagination/View/Standard.php';
$view = new A_Pagination_View_Standard($pager);
// display the data
echo '<table border="1">';
foreach ($pager->getItems() as $row) {
echo '<tr>';
echo '<td>' . $row['id'] . '</td><td>' . $row['name'] . '</td>';
echo '</tr>';
}
echo '</table>';
// display the pagination links
echo $view->render();- There are a number of examples that show different ways the classes can be used -- from do-it-yourself to standalone.
- There is support for ORDER BY functionality to sort the list. There are methods to generate column heading links to sort any column ascending/descending. Sort order is maintained while paging.
- The total number of items in the datasource is persisted RESTfully so, for example, COUNT() is only called one for database datasources.
- Request parameter names can be changed to remove conflicts and allow multiple pagers on one page.
- Pagination state values can be saved in the session if you want to be able to resume in the list where you left off -- when editing records in CRUD for example.
- Do these classes provide everything you need for pagination?
- What modifications would you make before using this in a project?
- What can we do to improve the code?
For the most automated use case, we will be providing a DataGrid that takes care of all HTML once the core classes have been finalized.
The code attachment is an older version
Latest code available at: http://skeleton.googlecode.com/