Магазин на Yii2, часть 10. Добавляем постраничную навигацию
15.05.2019
Теги: Web-разработка • Yii2 • ИнтернетМагазин • КаталогТоваров • Навигация • ПостраничнаяНавигация • Практика • Фреймворк
Сейчас на странице категории показываются все товары этой категории и всех ее потомков. Это подходит для небольшого каталога, но когда товаров много, страница будет очень большой. Давайте добавим постраничную навигацию и используем для этого класс Pagination
.
Сначала изменяем метод модели, отвечающий за получение списка товаров категории:
<?php namespace app\models; use yii\data\Pagination; use yii\db\ActiveRecord; class Category extends ActiveRecord { /*...*/ /** * Возвращает массив всех товаров в категории с идентификатором $id * и в ее потомках, т.е. в дочерних, дочерних-дочерних и так далее */ public function getCategoryProducts($id) { $id = (int)$id; // получаем массив идентификаторов всех потомков категории $ids = $this->getAllChildIds($id); $ids[] = $id; // для постаничной навигации получаем только часть товаров $query = Product::find()->where(['in', 'category_id', $ids]); $pages = new Pagination([ 'totalCount' => $query->count(), 'pageSize' => 10, // кол-во товаров на странице ]); $products = $query->offset($pages->offset) ->limit($pages->limit) ->asArray() ->all(); return [$products, $pages]; } /*...*/ }
Потом изменяем action
в контроллере, отвечающий за страницу списка товаров категории:
<?php namespace app\controllers; use app\models\Category; use app\models\Brand; use app\models\Product; use Yii; class CatalogController extends AppController { /*...*/ /** * Категория каталога товаров */ public function actionCategory($id) { $id = (int)$id; $temp = new Category(); // товары категории list($products, $pages) = $temp->getCategoryProducts($id); // данные о категории $category = $temp->getCategory($id); // устанавливаем мета-теги для страницы $this->setMetaTags( $category->name . ' | ' . Yii::$app->params['shopName'], $category->keywords, $category->description ); return $this->render( 'category', compact('category', 'products', 'pages') ); } /*...*/ }
И последнее — используем виджет LinkPager
в view-шаблоне views/catalog/category.php
для показа постраничной навигации:
<?php /* * Страница раздела каталога, файл views/catalog/category.php */ use app\components\TreeWidget; use app\components\BrandsWidget; use yii\helpers\Html; use yii\helpers\Url; use yii\widgets\LinkPager; ?> <section> <div class="container"> <div class="row"> <div class="col-sm-3"> <div class="left-sidebar"> <h2>Каталог</h2> <div class="category-products"> <?= TreeWidget::widget(); ?> </div> <h2>Бренды</h2> <div class="brand-products"> <?= BrandsWidget::widget(); ?> </div> </div> </div> <div class="col-sm-9"> <?php if (!empty($products)): ?> <h2><?= Html::encode($category['name']); ?></h2> <div class="row"> <?php foreach ($products as $product): ?> <div class="col-sm-4"> <div class="product-wrapper text-center"> <?= Html::img( '@web/images/products/medium/'.$product['image'], ['alt' => $product['name'], 'class' => 'img-responsive'] ); ?> <h2><?= $product['price']; ?> руб.</h2> <p> <a href="<?= Url::to(['catalog/product', 'id' => $product['id']]); ?>"> <?= Html::encode($product['name']); ?> </a> </p> <a href="#" class="btn btn-warning"> <i class="fa fa-shopping-cart"></i> Добавить в корзину </a> <?php if ($product['new']) { // новинка? echo Html::img( '@web/images/home/new.png', ['alt' => 'Новинка', 'class' => 'new'] ); } if ($product['sale']) { // распродажа? echo Html::img( '@web/images/home/sale.png', ['alt' => 'Распродажа', 'class' => 'sale'] ); } ?> </div> </div> <?php endforeach; ?> </div> <?= LinkPager::widget(['pagination' => $pages]); /* постраничная навигация */ ?> <?php else: ?> <p>Нет товаров в этой категории.</p> <?php endif; ?> </div> </div> </div> </section>
Сейчас ссылки постраничной навигации имеют вид:
http://server.com/catalog/category/12?page=3&per-page=10
Давайте изменим это, чтобы ссылки имели вид:
http://server.com/catalog/category/12/page/3
Для этого добавим еще пару параметров к настройкам Pagination
:
$pages = new Pagination([ 'totalCount' => $query->count(), 'pageSize' => 10, 'forcePageParam' => false, 'pageSizeParam' => false ]);
И еще одно правило для маршрутов в файл config/web.php
:
$config = [ /*...*/ 'components' => [ /*...*/ 'urlManager' => [ 'enablePrettyUrl' => true, 'showScriptName' => false, 'rules' => [ 'catalog/category/<id:\d+>/page/<page:\d+>' => 'catalog/category', 'catalog/category/<id:\d+>' => 'catalog/category', 'catalog/brand/<id:\d+>' => 'catalog/brand', ], ], ], /*...*/ ];
- Магазин на Yii2, часть 13. Страница товара и хлебные крошки
- Магазин на Laravel 7, часть 20. Показ отдельной страницы и верхнее меню всех страниц
- Магазин на Yii2, часть 35. Админка: загрузка картинок для страниц и страница 404
- Магазин на Yii2, часть 34. Показываем меню страниц в публичной части
- Магазин на Yii2, часть 33. Админка: приводим в порядок CRUD-код для страниц
- Магазин на Yii2, часть 32. Админка: удаление категорий и CRUD для страниц
- Магазин на Yii2, часть 31. Админка: загрузка изображений для категорий и брендов
Поиск: Web-разработка • Yii2 • Интернет магазин • Каталог товаров • Навигация • Постраничная навигация • Фреймворк • Pagination