Добавляем новостям пагинацию
Первым делом выбираем что-нибудь попроще на https://packagist.org/search/?q=pagination - мне приглянулся второй пункт, с kilte/pagination. Добавляем его в наш composer.json и устанавливаем на сервере.
Теперь пишем новый метод в Brevis\Controller:
/**
* Возвращает массив с постраничной навигацией
*
* @param $totalItems
* @param int $currentPage
* @param int $itemsPerPage
* @param int $neighbours
*
* @return array
*/
public function getPagination($totalItems, $currentPage = 1, $itemsPerPage = 10, $neighbours = 2) {
$pagination = new Pagination($totalItems, $currentPage, $itemsPerPage, $neighbours);
return $pagination->build();
}
А в начале файла указываем
use \Kilte\Pagination\Pagination as Pagination;
Всё, в нашем проекте уже есть постраничная навигация.
Дальше мы научим контроллер новостей её использовать, а шаблон - оформлять.
Меняем Controllers\News
В прошлый раз мы написали контроллер новостей, и научили его выводит заметки по alias или id. Для приятной постраничной навигации, от вывода по id придётся отказаться, потому что адреса, типа /news/2/, будут у нас отдельными страницами.
То есть, /news/the-first - это заметка в разделе новостей, а /news/3/ - это третья страница новостей.
Добавляем новые свойства в класс, для разбивки на страницы:
public $limit = 2;
public $page = 1;
private $_offset = 0;
private $_total = 0;
limit у нас уже был, я просто уменьшил его для наглядности.
Теперь меняем метод initialize():
public function initialize(array $params = array()) {
if (empty($params)) {
$this->redirect("/{$this->name}/");
}
// После адреса страницы указан параметр
elseif (!empty($params[0])) {
// Указано число, значит это номер страницы
// Реагируем только на вторую страницу и дальше
if (is_numeric($params[0]) && $params[0] > 1) {
// После номера нет косой, или наоборот, указано что-то еще
if (!isset($params[1]) || !empty($params[1])) {
// Делаем редирект на канонический адрес
$this->redirect("/{$this->name}/$params[0]/");
}
// В противном случае, сохраняем номер страницы и считаем,
// сколько строк нужно пропустить от начала в выборке
$this->page = (int)$params[0];
$this->_offset = ($this->page - 1) * $this->limit;
}
// Указано не число - это alias новости
else {
// Здесь всё осталось как раньше, только кода поменьше
$c = $this->core->xpdo->newQuery('Brevis\Model\News', array('alias' => $params[0]));
if ($news = $this->core->xpdo->getObject('Brevis\Model\News', $c)) {
$this->item = $news;
}
}
// Если не выбрана заметка и offset пустой, то делаем редирект в корень раздела
// Это будет в случае, если в параметрах указана какая-то ерунда
if (!$this->_offset && !$this->item) {
$this->redirect("/{$this->name}/");
}
}
return true;
}
В методе getItems() добавляем пропуск результатов от начала - offset, подсчёт общего количества строк и редирект в корень раздела, если указана несуществующая страница.
$c = $this->core->xpdo->newQuery('Brevis\Model\News');
// Считаем общее количество новостей
$this->_total = $this->core->xpdo->getCount('Brevis\Model\News');
// Если пропуск от начала больше, чем общее количество - указана несуществующая страница
if ($this->_offset >= $this->_total) {
// Редиректим в корень раздела
$this->redirect("/{$this->name}/");
}
$c->select($this->core->xpdo->getSelectColumns('Brevis\Model\News', 'News'));
$c->sortby('id', 'DESC');
// А здесь, помимо лимита, добавляем и пропуск от начала
$c->limit($this->limit, $this->_offset);
Остался последний штрих - нам нужно получить массив в пагинацией после вызова getItems(). Это мы делаем в методе run()
$data = array(
'title' => 'Новости',
'pagetitle' => 'Новости',
'items' => $this->getItems(),
// Пагинация с нашими свойствами: total, page и limit
'pagination' => $this->getPagination($this->_total, $this->page, $this->limit),
'content' => '',
);
Осталось оформить странички в шаблоне.
Меняем news.tpl
Как указано в документации kilte/pagination, компонент должен вернуть нам массив номеров страниц с указанием их типа: текущая, предыдущая и т.д.
Так что, просто добавляем прокрутку этого массива с оформлением в наш шаблон:
{if $pagination}
<nav>
<ul class="pagination">
{foreach $pagination as $page => $type}
{switch $type}
{case 'first'}
<li><a href="/news/">«</a></li>
{case 'last'}
<li><a href="/news/{$page}/">»</a></li>
{case 'less', 'more'}
{case 'current'}
<li class="active"><a href="/news/{$page}/">{$page}</a></li>
{case default}
<li><a href="/news/{$page}/">{$page}</a></li>
{/switch}
{/foreach}
</ul>
</nav>
{/if}
Думаю, тут всё понятно без комментариев. Обратите только внимание на то, что я пропускаю страницы more и less, потому что, на мой взгляд, они не нужны.
Вот и всё, наша постраничная навигация уже работает - можно проверять!
Заключение
Думаю, после прохождения курса, вам стало ясно, насколько легко и просто можно строить сайты самостоятельно, используя свои и чужие готовые решения, без CMS и тяжелых фреймворков.
Я ни в коем случае не призываю вас отказываться от них и делать всё самостоятельно, нет! Просто знайте, что где-то там внутри примерно такой же код, как мы написали с вами на этих курсах. Конечно, обычно он более продвинутый и крутой, но базовые принципы везде одинаковы.
Надеюсь, мои уроки помогут вам разбираться в PHP немного лучше. Если у вас остались вопросы - задавайте!
Оказалось, что я забыл написать еще один урок - вот и он.
0
👍
👎
❤️
🔥
😮
😢
😀
😡
2 593
24.06.2015, 11:04:00
8 комментариев
Семён Лобачевский
26.06.2015, 23:34:06
Спасибо за финальный урок и курс в целом! Стало более понятно как устроены php фреймворки и любимый MODx в частности)
Василий Наумкин
27.06.2015, 01:10:46
На здоровье!
Похоже, ты единственный, кто всё прочитал =)
Перетягин Илья
27.06.2015, 02:31:48
Все впереди ))) Я первый урок осиливал около 3-4 дней, завтра буду читать второй, но если они по сложности идут по нарастающей, то до третьего не добраться ))))
Василий Наумкин
27.06.2015, 10:02:40
Да ладно тебе! Делай как написано и через какое-то время придёт понимание. Тем более, всё закоммичено на GitHub, поэтапно.
Я так разработку компонентов для MODX осваивал - просто методом тыка повторял чужие разработки, пока не дошло, откуда какие файлы и зачем берутся.
Перетягин Илья
27.06.2015, 16:27:30
Тут больше проблема в самом коде, так как программирование больше хобби, то и опыта мало в этом, и некоторые моменты не понятны, приходиться вычитывать на других ресурсах, от сюда и время изучения.
На самом деле все толково написано, просто понадобиться больше времени чем ожидалось.
Василий Наумкин
27.06.2015, 19:01:02
Так спрашивай здесь, расскажу.
Перетягин Илья
27.06.2015, 23:01:44
Да там вопросы банальные, даже ка кто стыдно спрашивать..... Сейчас напишу один в первой теме
Алексей
22.08.2015, 19:32:39
Ждём урока по Ajax )
bezumkin.ru
Личный сайт Василия Наумкина
Прямой эфир
Василий Наумкин
23.12.2024, 05:33:00
В MODX сначала создали проблему, автоматически генерируя адреса, а потом "решили" заморозкой.
Так ч...
Дмитрий
14.12.2024, 09:10:38
Василий, прошу прощения, тупанул, не разобрался сразу. Фреймворк отличный! "Чистый лист" на vue, рис...
Василий Наумкин
05.12.2024, 20:01:14
В итоге основная ошибка была в неправильном общем root в Nginx, из-за чего запросы не улетали на фай...
Василий Наумкин
01.07.2024, 11:56:41
Да, верно, именно так.
А в контроллере, скорее всего, ловить данные методом post.
Василий Наумкин
26.06.2024, 09:38:15
О, точно, вылезает если не залогинен.
Спасибо, исправил!
Василий Наумкин
09.04.2024, 04:45:01
> Ошибка 500
Это не похоже на ошибку Nginx, это скорее всего ошибка PHP - надо смотреть его логи.
...
Уровни подписки
Спасибо!
500 ₽ в месяц
Эта подписка ничего не даёт, просто возможность сказать спасибо за мои заметки. Подписчики отмечаются зелёненьким цветом в комментариях.
Большое спасибо!
1 000 ₽ в месяц
И эта подписка не даёт ничего, кроме оранжевого цвета в комментариях и возможности сказать спасибо, но уже большое!