Для постраничной навигации (pagination) в Kohana 3.2 использую модуль:
https://github.com/kloopko/kohana-pagination
Использовать этот модуль достаточно просто:
1. Распаковываем архив в папку с модулями /modules/pagination/
2. Подключаем модуль в bootstrap.php
Kohana::modules(array( // 'auth' => MODPATH.'auth', // Basic authentication // 'cache' => MODPATH.'cache', // Caching with multiple backends // 'codebench' => MODPATH.'codebench', // Benchmarking tool 'database' => MODPATH.'database', // Database access // 'image' => MODPATH.'image', // Image manipulation 'orm' => MODPATH.'orm', // Object Relationship Mapping // 'unittest' => MODPATH.'unittest', // Unit testing // 'userguide' => MODPATH.'userguide', // User guide and API documentation 'pagination' => MODPATH.'pagination', // Pagination )
3. Тут же в bootstrap.php создаем роут для постраничеой навигации:
Route::set('catalog', 'catalog(/<category>(/<page>))') ->defaults(array( 'directory' => 'index', 'action' => 'index', 'controller' => 'catalog', ));
4. Из папки modules/pagination/config/ в application/config копируем файл
настроек pagination.php. Мой вариант конфига:
'default' => array( 'current_page' => array('source' => 'route', 'key' => 'page'), // откуда брать параметры из строки или роута и ключ параметров // source: "query_string" or "route" 'total_items' => 0, //Всего элементов 'items_per_page' => 10, //элементов на страницу 'view' => 'pagination/basic', //Шаблон 'auto_hide' => TRUE, // Скрывать вывод пагинации, если он не нужен 'first_page_in_url' => FALSE, // подставлять единицу в url к первой странице )
4. В контроллере пишем примерно такой код:
// получаем общее количество (в моем случае) товаров $count = ORM::factory('product')->count_all(); // передаем значение количества товаров в модуль pagination и формируем ссылки $pagination = Pagination::factory(array('total_items' => $count)); //получаем товары с указанной позиции ($pagination->offset) //и указанное количество на страницу ($pagination->items_per_page) $products = ORM::factory('product') ->limit($pagination->items_per_page) ->offset($pagination->offset) ->find_all(); //выводим данные в вид $this->template->main = View::factory('index/v_products', array('products' => $products, 'pagination' => $pagination ));
В итоге получаем например список из $pagination->items_per_page товаров, а под ним ссылки ввиде:
Страницы: << Пред. 1 2 3 След. >>
P.S. при использовании данного модуля было замечено, что не при всех роутах он работает корректно.
Например, есть роут:
Route::set('admin', 'admin(/<controller>(/<action>(/<id>)))') ->defaults(array( 'directory' => 'admin', 'controller' => 'main', 'action' => 'index', ));
и контроллер order с экшеном index:
$allorders = ORM::factory('order')->order_by('date','DESC'); $count = $allorders->count_all(); $pagination = Pagination::factory(array('total_items' => $count));
Так вот, в нем, модуль нормальных ссылок не дает.
В модуле используется следующий механизм формирования ссылок:
URL::site($this->_route->uri(array_merge($this->_route_params, array($this->config['current_page']['key'] => $page))).$this->query());
где:
$this->_route = $request->route();
$this->_route_params = $request->param();
$this->config[‘current_page’][‘key’] = ‘id’;//параметр из роута
На текущий момент поборол это написанием дополнительного роута:
Route::set('adminorders', 'admin/orders(/<id>)') ->defaults(array( 'directory' => 'admin', 'controller' => 'orders', 'action' => 'index', ));
В будущем надеюсь побороть эту проблему.
Нашел решение проблемы с некоректной работой модуля пагинации:
$pagination = Pagination::factory(array( 'total_items' => $count, 'items_per_page' => 50, )) ->route_params(array( 'controller' => Request::current()->controller(), 'action' => Request::current()->action(), ));
т.е. передаем дополнительные параметры о текущем контроллере и экшене в модуль пагинации:
->route_params(array( 'controller' => Request::current()->controller(), 'action' => Request::current()->action(), ));