Магазин на Yii2, часть 11. Пагинация и мета-теги для брендов

27.05.2019

Теги: Web-разработкаYii2ИнтернетМагазинКаталогТоваровПрактикаФреймворк

Мы добавили мета-теги и постраничную навигацию для страниц категорий. Теперь сделаем это для страниц брендов. Пагинация для товаров бренда мало чем отличается от пагинации для товаров категории. А в таблице brand базы данных предусмотрены поля keywords и description, которые будут заполняться при создании нового бренда через панель управления.

<?php
namespace app\models;

use yii\data\Pagination;
use yii\db\ActiveRecord;
use Yii;

class Brand extends ActiveRecord {

    /*...*/

    /**
     * Возвращает массив всех товаров бренда с идентификатором $id
     */
    public function getBrandProducts($id) {
        $id = (int)$id;
        // для постаничной навигации получаем только часть товаров
        $query = Product::find()->where(['brand_id' => $id]);
        $pages = new Pagination([
            'totalCount' => $query->count(),
            // количество товаров на странице теперь в настройках
            'pageSize' => Yii::$app->params['pageSize'],
            'forcePageParam' => false,
            'pageSizeParam' => false
        ]);
        $products = $query->offset($pages->offset)
            ->limit($pages->limit)
            ->asArray()
            ->all();
        return [$products, $pages];
    }
}
<?php
namespace app\controllers;

use app\models\Category;
use app\models\Brand;
use app\models\Product;
use Yii;

class CatalogController extends AppController {

    /*...*/

    /**
     * Список товаров бренда с идентификатором $id
     */
    public function actionBrand($id) {
        $id = (int)$id;
        $temp = new Brand();
        // товары бренда
        list($products, $pages) = $temp->getBrandProducts($id);
        // данные о бренде
        $brand = $temp->getBrand($id);
        // устанавливаем мета-теги
        $this->setMetaTags(
            $brand->name . ' | ' . Yii::$app->params['shopName'],
            $brand->keywords,
            $brand->description
        );
        return $this->render(
            'brand',
            compact('brand', 'products', 'pages')
        );
    }

}

Добавляем в view-шаблон виджет постраничной навигации:

<?php
/*
 * Страница списка товаров бренда, файл views/catalog/brand.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">
                <h2>Каталог</h2>
                <div class="category-products">
                    <?= TreeWidget::widget(); ?>
                </div>

                <h2>Бренды</h2>
                <div class="brand-products">
                    <?= BrandsWidget::widget(); ?>
                </div>
            </div>

            <div class="col-sm-9">
                <?php if (!empty($products)): /* выводим товары бренда */ ?>
                    <h2><?= Html::encode($brand['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>

Выносим в настройки количество товаров на странице при пагинации, файл config/params.php

<?php
return [
    'adminEmail' => 'admin@example.com',
    'senderEmail' => 'noreply@example.com',
    'senderName' => 'Example.com mailer',
    /*
     * Название магазина, например «Lamoda» или «WildBerries»
     */
    'shopName' => 'Магазин одежды и обуви',
    /*
     * Значения по умолчанию для мета-тегов title, keywords и description
     */
    'defaultTitle' => 'Интернет-магазин модной одежды и обуви',
    'defaultKeywords' => 'одежда, обувь, мужская, женская, детская, зимняя, летняя',
    'defaultDescription' => 'Коллекции женской, мужской, детской одежды и обуви',
    /*
     * Количество товаров на странице для постраничной навигации
     */
    'pageSize' => 10,
];

И добавляем еще одно правило в config/web.php:

$config = [
    /* ... */
    'components' => [
        /* ... */
        'urlManager' => [
            /* ... */
            'rules' => [
                'catalog/category/<id:\d+>/page/<page:\d+>' => 'catalog/category',
                'catalog/category/<id:\d+>' => 'catalog/category',
                'catalog/brand/<id:\d+>/page/<page:\d+>' => 'catalog/brand',
                'catalog/brand/<id:\d+>' => 'catalog/brand',
            ],
        ],
    ],
    /* ... */
];

Поиск: Web-разработка • Yii2 • Интернет магазин • Каталог товаров • Практика • Фреймворк

Каталог оборудования
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Производители
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Функциональные группы
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.