Pagination in DotKernel
When we have a list of items, and there are a lot of them, pagination is a must. In DotKernel, this is how we implemented pagination, helped by the Zend_Paginator.
In Controller:
case 'product-list':
$pageTitle = 'List Products';
$page = (isset($request['page'])) ? $request['page'] : 1;
$list = $productModel->getProductsList($page);
$productView->productList('productList', $list, $page);
break;
In Model, we have:
/**
* Get product list
* @access public
* @param int $page [optional]
* @return array(array(), Zend_Paginator_Adapter())
*/
public function getProductsList($page=1)
{
$select = $this->db->select()
->from(array('a'=>'products'), array('id','title','created','active'));
$paginatorAdapter = new Zend_Paginator_Adapter_DbSelect($select);
($page == 1) ?
$select->limit($this->settings->results_per_page) :
$select->limit($this->settings->results_per_page, ($page-1)*$this->settings->results_per_page);
$data = $this->db->fetchAll($select);
return array('data'=> $data,'paginatorAdapter'=> $paginatorAdapter);
}
You may note that for Zend_Paginator_Adapter we used the whole select query, and added limit only for the data we retrieve. This will return an array with 2 values: $data and $paginatorAdapter.
$data will be used in View to list the current records for the specific page.
$paginatorAdapter will be used as a parameter in View for the Zend_Paginator() class
In View there is:
/**
* Display product list
* @access public
* @param string $templateFile
* @param array $list
* @param int $page
* @return void
*/
public function productList($templateFile, $list, $page)
{
$this->tpl->setFile('tpl_main', 'media/' . $templateFile . '.tpl');
$this->tpl->setBlock('tpl_main', 'list', 'list_block');
$this->tpl->paginator($list['paginatorAdapter'],$page);
foreach ($list['data'] as $k => $v)
{
$this->tpl->setVar('ID', $v['id']);
$this->tpl->setVar('TITLE', $v['title']);
$this->tpl->setVar('CREATED', $v['created']);
$this->tpl->parse('list_block', 'list', true);
}
}
Method paginator from View has the following content
/**
* Create the pagination, based on how many data
* @access public
* @param array $data
* @param int $current_page [optional]
* @return string
*/
protected function paginator($adapter, $currentPage = 1)
{
$paginator = new Zend_Paginator($adapter);
$paginator->setItemCountPerPage($this->settings->results_per_page);
$paginator->setCurrentPageNumber($currentPage);
$paginator->setPageRange(10);
$paginator->totalItems = $adapter->count();
$page = $paginator->getPages();
$this->setFile('page_file', 'paginator.tpl');
$this->setVar('TOTAL_ITEMS', $paginator->totalItems);
$this->setVar('TOTAL_PAGES', $paginator->count());
$this->setBlock('page_file', 'first', 'first_row');
$this->setBlock('page_file', 'previous', 'previous_row');
$this->setBlock('page_file', 'next', 'next_row');
$this->setBlock('page_file', 'current_page', 'current_row');
$this->setBlock('page_file', 'other_page', 'other_row');
$this->setBlock('page_file', 'pages', 'pages_row');
$this->setBlock('page_file', 'last', 'last_row');
$param = Zend_Registry::get('param');
$link = (array_key_exists('page',$param)) ? '' : 'page/';
if ($page->first != $page->current)
{
$this->setVar('PREVIOUS_LINK',$link.($page->current-1));
$this->parse('previous_row', 'previous', TRUE);
$this->setVar('FIRST_LINK', $link.'1');
$this->parse('first_row', 'first', TRUE);
}
else
{
$this->parse('previous_row', '');
$this->parse('first_row', '');
}
if ($page->last>0 && $page->last != $page->current)
{
$this->setVar('NEXT_LINK',$link.$page->next);
$this->parse('next_row', 'next', TRUE);
$this->setVar('LAST_LINK', $link.$page->last);
$this->parse('last_row', 'last', TRUE);
}
else
{
$this->parse('next_row', '');
$this->parse('last_row', '');
}
foreach ($page->pagesInRange as $val)
{
$this->setVar('PAGE_NUMBER', $val);
$this->parse('other_row','');
$this->parse('current_row','');
if($val == $page->current)
{
$this->parse('current_row','current_page', TRUE);
}
else
{
$this->setVar('PAGE_LINK', $link.$val);
$this->parse('other_row','other_page', TRUE);
}
$this->parse('pages_row', 'pages', TRUE);
}
$this->parse('PAGINATION', 'page_file');
}
The template file for pagination is paginator.tpl:
<table cellpadding="0" cellspacing="1">
<tr>
<td width="50">
<span>{TOTAL_ITEMS} Items</span>
</td>
<td width="100">
<span>Pages ({TOTAL_PAGES}): </span>
</td>
<td>
<ul>
<!-- BEGIN first -->
<li>
<a href="{FIRST_LINK}">First</a>
</li>
<!-- END first -->
<!-- BEGIN previous -->
<li>
<a href="{PREVIOUS_LINK}"> << </a>
</li>
<!-- END previous -->
<!-- BEGIN pages -->
<!-- BEGIN current_page -->
<li>
<p>{PAGE_NUMBER}</p>
</li>
<!-- END current_page -->
<!-- BEGIN other_page -->
<li>
<a href="{PAGE_LINK}">{PAGE_NUMBER}</a>
</li>
<!-- END other_page -->
<!-- END pages -->
<!-- BEGIN next -->
<li>
<a href="{NEXT_LINK}"> >> </a>
</li>
<!-- END next -->
<!-- BEGIN last -->
<li>
<a href="{LAST_LINK}">Last</a>
</li>
<!-- END last -->
</ul>
</td>
</tr>
</table>
Also in index.php we have added a new line before instantiating Dot_Kernel class
$registry->param = $request;
For more details visit the trunk folder on DotKernel Repository
Leave a Reply