Start Using Pagination

Using Pagination in Windwalker is very easy, but you must know how to count pages in your SQL.

A pagination always need 3 integers, Total rows, Items per page, and Current page.

For SQL and programming, this 3 integers will be Total, Limit, and Offset.

Count Total Rows

Some times we will fetch items from database by SQL which looks like this:

SELECT * 
FROM sakuras
WHERE state = 1
    AND author = 25
ORDER BY created
LIMIT 0, 20

This is a common way to count total rows by remove LIMIT element and select COUNT(*).

SELECT COUNT(*) 
FROM sakuras
WHERE state = 1
    AND author = 25
ORDER BY created

Use the second query we'll fetch total rows of first query without limit.

Another Way to Count Total

Use SQL_CALC_FOUND_ROWS in only MySQL.

SELECT SQL_CALC_FOUND_ROWS *
FROM sakuras
WHERE state = 1
    AND author = 25
ORDER BY created
LIMIT 0, 20

And use SELECT FOUND_ROWS() to fetch total rows, this way will a little faster than first way if you set index correctly , but only MySQL works.

Count Total if SQL has GROUP

If you add group in your SQL, the COUNT(*) will be incorrect, we must use an inefficient way to count all results.

This is the main query of yours.

SELECT *
FROM sakuras AS a
    LEFT JOIN flowers AS b ON a.flower_id = b.id
WHERE state = 1
    AND author = 25
ORDER BY created
LIMIT 0, 20
GROUP a.id

Remove LIMIT then execute this SQL:

SELECT *
FROM sakuras AS a
    LEFT JOIN flowers AS b ON a.flower_id = b.id
WHERE state = 1
    AND author = 25
ORDER BY created
GROUP a.id

And use ReaderCommand::count():

$total = $db->getReader($sql)->count();

Create Pagination

This is an example to fetch rows and total:

$limit = 20;
$page  = $input->get('page', 1);
$start = ($page - 1) * $limit;

$query = $db->getQuery(true);

// Basic query
$query->select('*')
    ->from('sakuras')
    ->where('state = 1')
    ->where('author = 25')
    ->order('created')
    ->limit($limit, $start);

// Load rows
$items = $db->getReader($query)->loadObjectList();

// Count total, clear non-necessary sql elements
$query->clear(array('select', 'limit', 'offset', 'order'))
    ->select('COUNT(*)');

$total = $db->getReader($query)->loadResult();

// Create pagination object
$pagination = new Pagination($total, $page, $limit);

// Get PaginationResult object
$paginData = $pagination->getResult();

Pagination Result

PaginationResult to an object contains pagination information, you can get pages data from this object:

$paginData = $pagination->getResult();

$paginData->getFirst();    // page number
$paginData->getLess();     // page number
$paginData->getPrevious(); // page number
$paginData->getPages();    // An array or pages
$paginData->getNext();     // page number
$paginData->getMore();     // page number
$paginData->getLast();     // page number

// Print all
print_r($paginData->getAll());

The output is:

Array
(
    [1] => first
    [7] => less
    [8] => lower
    [9] => lower
    [10] => lower
    [11] => lower
    [12] => current
    [13] => higher
    [14] => higher
    [15] => higher
    [16] => higher
    [17] => more
    [25] => last
)

You can use this array to build your pagination HTML.

pagination

Use Built-in Pagination Template

render() method will auto render pagination HTML, the default template is windwalker.pagination.default. The first argument (route resources name) is required because pagination use Router to get page url.

echo $pagination->render('flower@sakuras');

Use Your Own Template

Add your template file in /templates/windwalker/pagination/default.php, Windwalker renderer will auto find it to replace built-in template.

Or use second argument to point to other template:

echo $pagination->render('flower@sakuras', 'mywidget.pagination');

See also: Widget and Renderer


If you found a typo or error, please help us improve this document.