В данном уроке мы с вами поговорим о модуле формирования постраничных ссылок — так называемом пагинаторе. Вместе с Коханой данный модуль не идет, но проблем с его нахождением на просторах интернета не возникает. До этого я пользовался своим пагинатором, но он несколько кривоват и недоделан (хотя стоит на паре моих сайтов и даже работает). А недавно мне понадобилось установить пагинатор на очередной разрабатываемый на Кохане сайт и я подумал, почему бы не совместить приятное с полезным, — поковырять полуофициальный модуль пагинации и заодно написать по нему урок. Потому что, несмотря на простоту нахождения пагинатора, не факт, что вам попадется новая версия и вот тогда сразу возникнут проблемы с совместимостью и прийдется применять напильник. Поэтому не мучайтесь и скачайте модуль, абсолютно точно работающий на Kohana v3.2
Как вы помните, все модули мы размещаем в папке modules и этот не станет исключением, поэтому распакуйте его к остальным модулям. Далее рекомендуется скопировать файл конфигурации config.php из modules/pagination/config в /application/config/, чтобы все изменения производить непосредственно в папке нашего проекта, но это в принципе необязательно, так как их можно делать и при создании объекта.
В конфигурационном файле лежит такой вот массив с параметрами:
return array( // Application defaults 'default' => array( 'current_page' => array('source' => 'query_string', '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, ), );
Давайте рассмотрим их:
current_page — этот параметр также содержит массив, в котором source отвечает за формирование адреса («query_string» — будет с гет-параметрами, а «route» — с mod rewrite), а key — это название параметра в роуте;
total_items — общее количество элементов (статей, изображений итд), которые мы будем разбивать на страницы. Стоит 0, но необходимо поменять;
items_per_page — количество элементов на странице (по умолчанию 10);
view — шаблон пагинатора. В комплектации идет два шаблона. Простой и посложнее. Я пользуюсь вторым;
auto_hide — если стоит «true», то при количестве страниц меньше двух пагинатор выводиться не будет;
first_page_in_url — если стоит «true», то добавляет единицу к адресу первой страницы.
Поменяйте данный массив на такой:
return array( // Application defaults 'default' => array( 'current_page' => array('source' => 'route', 'key' => 'page'), // source: "query_string" or "route" 'total_items' => 0, 'items_per_page' => 10, 'view' => 'pagination/floating', 'auto_hide' => TRUE, 'first_page_in_url' => FALSE, ), );
Следующее, что мы делаем — это включаем данный модуль в bootstrap.php, т.е. просто дописываем к списку модулей следующую строку:
'pagination' => MODPATH.'pagination', // Pagination
Там же в bootstrap.php посмотрите, чтобы параметр в роуте, отвечающем за страницу с пагинацией, назывался page. У меня таких вариаций страниц оказалось целых две. Допустим, страница вида www.site.ru/category/3 выводит третью страницу из списка всех категорий товаров, а страница www.site.ru/category/1-computers/3 выводит уже третью страницу категории «Компьютеры». Мне пришлось написать два роута:
Route::set('allcategory', 'category(/<page>)', array('page' => '[0-9]+')) ->defaults(array( 'controller' => 'category', 'action' => 'index', )); Route::set('category', 'category(/<id>-<catname>(/<page>))', array('id' => '[0-9]+'), array('page' => '[0-9]+')) ->defaults(array( 'controller' => 'category', 'action' => 'index', ));
Вообщем-то оно даже работает и работает правильно. Но если кто знает способ лучше, милости просим в комментарии.
Итак, все подготовительные работы закончены. Осталось только вывести наш пагинатор. Делается это очень просто. Все, что нужно знать — общее количество элементов. Так как это уже не тема данного урока, то предположим, что у нас 100 статей. Тогда в контроллере просто создаете объект и передаете ему этот параметр следующим образом:
$total_items = 100; //Это вы как будто посчитали количество элементов $content->pagination = Pagination::factory(array('total_items' => $total_items));
Естественно здесь же можно поменять и другие параметры. Теперь осталось только в шаблоне в нужном месте написать:
<?php echo $pagination; ?>
И вы получите свой пагинатор. Не забудьте только приукрасить его в шаблоне, а то там все на английском. Должно у вас получиться что-то подобное Этому (пагинатор кликабелен). Удачи!
Пожалуйста, зарегистрируйтесь для комментирования.
спасибо большое, но к сожалению не очень помогло. Как связать создание пагинатора в контроллере и запрос offset/limit в модели?
контроллер
bind(‘articles’, $articles);
$article = new Model_Article();
$articles = $article->get_all();
$content->pagination = Pagination::factory(array(‘total_items’ => 100));
$this->template->content = $content;
}
}
Модель
from($this->_tableArticles)->limit(1)->offset(1)
->execute();
}
передавать объект пагинатора в модель? или как получать значения?
Количество записей на страницу мы знаем (limit).
Зная количество записей на страницу и текущий номер страницы $this->request->param(‘page’) можно вычислить offset. Делаем запрос, получаем нужные записи.
А в чем может быть дело, если у меня ссылки из этой навигации ведут на главную? Выводит все как положено с лимитом и сама навигация выведена, но при клике следующая или 2 переходит на главную(((
А как выглядит при этом ссылка в адресной строке ? С цифрами или без ?
Без…я нашел уже выход…такой вот
$pagination = Pagination::factory(array(
‘total_items’ => $count,
))
->route_params(array(
‘controller’ => Request::current()->controller(),
‘action’ => Request::current()->action(),
));
Подскажите как сделать так что бы постраничный вывод шел после параметра…допусти так ((/(/(/)(/)))) у меня есть несколько категорий и не охота под каждую делать свой экшен только из-за pagination…ведь проще выводить по категориям…Очень нужно такое решение…как осуществить?
Написать такой роут, чтобы на один action кидало
так он на него и кидает…и вывод получается всех материалов…а не по категориям((( у меня в экшене перехватывается параметр cat и по нему вывод из базы…можно подробнее как все это работает?
SELECT * FROM table WHERE category = текущая категория LIMIT ….
и подсчет записей с учетом категории
выводит он все правильно…но ссылки не формирует…ссылки на страницы 1,2,3 и т.д. получаются без категорий
и pagination не формерует ссылку в виде controller/action/cat/а потом уже номер страницы
ссылка получается вида controller/action/ номер страницы и категория теряется((
Не то…(( Я на форуме сейчас все подробно опишу…может кто еще подскажет.
Ну это я с одного из своих скопировал. А что, роут в статье не подходит ?
Он как раз формирует пагинатор по категориям на этом сайте http://www.host4pics.ru
Спасибо! Решение оказалось проще простого…я тут вверху писал что пришлось передавать параметры…вот
$pagination = Pagination::factory(array(
‘total_items’ => $count,
))
->route_params(array(
‘controller’ => Request::current()->controller(),
‘action’ => Request::current()->action(),
и просто добавил сюда еще параметр ‘cat’ => $this->request->param(‘cat’);
));
теперь все ОК!))
Добрый вечер, все сделал по инструкции, но все ссылки в пагинаторе ведут на домашнюю страницу сайта, а именно на http://site.ru/ , имею ввиду на мой домен все ссылки идут, что делать, в чем может быть проблема ?
Уесли вручную вбиваю адрес, то все корректно работает
Добрый день!
Возникла проблема с пагинатоом.
Есть роут
Route::set(‘static’, ‘(/)’, array(‘action’ => ‘index|about|contacts|showpages’))
->defaults(array(
‘controller’ => ‘static’,
));
За отображение пагинатора отвечает метод showpages контроллера static
public function action_showpages()
{
$content = »;
$objects = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
$pag_data = array
(
‘total_items’ => count($objects),
‘items_per_page’ => 3,
‘view’ => ‘pagination/mypager’,
‘first_page_in_url’ => true,
);
$content = Pagination::factory($pag_data)->route_params( array(
‘controller’ => Request::current()->controller(),
‘action’ => Request::current()->action(),
))->render();
$this->template->content = $content;
}
Этот пример работает, но работает с использованием параметра ?page. Пагинатор генерирует ссылки типа kohana/showpages/?page=2
Я хочу использовать роут для приведения ссылок пагинатора к типу kohana/showpages/2
ДЛя этого я добавил в $pag_data
‘current_page’ => array(‘source’ => ‘route’, ‘key’ => ‘page’),
и создал роут
Route::set(‘pagination’, ‘(/)’, array(‘page’ => ‘[0-9]+’))
->defaults(array(
‘controller’ => ‘static’,
‘action’ => ‘showpages’,
));
Но пагинатор для всех ссылок генерирует kohana/showpages
Что я сделал не так?
Для формирования ссылок вида /2 нужно параметр
поменять на
Я так и сделал. Но не работает Странно
А подскажите какой роут у вас используется на http://kohanaframework.su/kohana/articles для articles?
а то не могу никак сообразить, как вы сделали так, что бы по
http://kohanaframework.su/kohana/articles/2 — были страницы, а по
http://kohanaframework.su/kohana/articles/articlе2 — была статья.
Спасибо.