Как сделать ЧПУ пагинацию на Yii2?

Сделать ЧПУ url через urlManager получилось, а вот при подключении пагинации параметры передаются в виде mysite.ru/controllerName?page=2&per-page=2. Как сделать пагинацию вида mysite.ru/controllerName/page/2 ?
Так же требуется url первой страницы менять с такого mysite.ru/controllerName?page=1&per-page=2 на такой mysite.ru/controllerName
  • Вопрос задан
  • 12780 просмотров
Решения вопроса 1
affka
@affka
http://affka.ru
для этого нужно в конфиге в url manager прописать rules, аналогично как это делалось в yii1. примерно так:
'urlManager': [
  'rules': [
    'controllerName/<page>': 'controllerName/index'
  ]
]


подробнее тут - www.yiiframework.com/doc-2.0/guide-url.html#parame...
Ответ написан
Пригласить эксперта
Ответы на вопрос 3
mulat
@mulat
seo, php, yii2
Как раз только что с этим разобрался. Приведу пример кода из своего проекта.
Вариант для yii\widgets\ListView
Контроллер:
$dataProvider = new ActiveDataProvider([
            'query' => Post::find()->andWhere(['category_id' => $model->id]),
            'pagination' => [
                // Размер выводимых элементов на страницу. 
                // Беру из настроек своего модуля blog
                'pageSize' => Yii::$app->getModule('blog')->postPerPage,
                // Размер эл-тов на страницу по умолчанию. Зачем нужен - поясню после кода
                'defaultPageSize' => Yii::$app->getModule('blog')->postPerPage,
                // Имя параметра, содержащего номер текущей страницы. 
                // (если Ваш отличается от дефолтного 'page')
                'pageParam' => 'pageNum',
                // Так подавляется ссылка на первую страницу вида /category-name-х/1/
                // Вместо неё выведется  /category-name-х/
                'forcePageParam' => false,
            ]
        ]);


Значение 'defaultPageSize' нужно установить равным значению 'pageSize' для того, чтобы подавить добавление классом Pagination параметра 'per-page' в урлы постранички. Но это нужно для того случая, когда не устраивает значение родного 'pageSize'. По-моему равно 20-ти.


Так же требуется url первой страницы менять с такого mysite.ru/controllerName?page=1&per-page=2 на такой mysite.ru/controllerName

Этот момент решается установкой параметра 'forcePageParam' в значение false.

Для того, чтобы подхватывался route из Вашего urlManager, нужно чтобы описанный в менеджере pattern содержал правильные имена параметров. Т.е. в настройках класса Pagination - значение 'pageParam' по умолчанию задано как 'page'. Значит pattern для урлов должен быть такого плана:
//...
// Category with pager
 [
    'pattern' => '<alias:[\w\-]+>/<page:\d+>',
    'route' => 'blog/category/index',
    'suffix' => '/'
  ],
//...


В моём случае pattern для урлов такой:
'pattern' => '<alias:[\w\-]+>/<pageNum:\d+>'

P.S.
В итоге мне самому этот вариант не подошёл, т.к. я хотел в постраничке оставить только ссылки на сами страницы без ссылок Следющий и Предыдщий пост. Не нашёл как сделать под ListView. А в LinkPager без проблем.
Вариант для yii\widgets\LinkPager
Контроллер:
$query = Post::find()->andWhere(['category_id' => $model->id]);
        $countQuery = clone $query;
        $pages = new Pagination([
            'totalCount' => $countQuery->count(),
            'pageSize' => Yii::$app->getModule('blog')->postPerPage,
            'defaultPageSize' => Yii::$app->getModule('blog')->postPerPage,
            'pageParam' => 'pageNum',
            'forcePageParam' => false,
        ]);
        $postModels = $query->offset($pages->offset)->limit($pages->limit)->all();

        return $this->render('index', [
            'postModels' => $postModels,
            'pages' => $pages,
        ]);


Представление:
echo LinkPager::widget([
            'pagination' => $pages,
            // Отключаю ссылку "Следующий"
            'nextPageLabel' => false,
            // Отключаю ссылку "Предыдущий"
            'prevPageLabel' => false,
        ]);


Вроде на оба вопроса ответил.

P.S.

Использую доработанный LinkPager. В частности ради настройки `activeLinkable` (не ссылаться на активную страницу), отображения номера конечной страницы и вывода островной нумерации:
1,2,3,4 ... 44 [45] 46 ... 999
Ответ написан
Head-Hunter
@Head-Hunter
<?= ListView::widget([
            'dataProvider' => $dataProvider,
            'itemView' => '_list',
            'layout' => "{items}\n{pager}",
            'summary' => Module::t('view', 'SHOW {count} FROM {totalCount}'),
            'emptyText' => Module::t('view','NO_PUBLISHED_TERMINS_FOUND'),
            'emptyTextOptions' => [
                'tag' => 'p'
            ],
            'itemOptions' => [
                'tag' => 'div',
                'class' => 'news-item',
            ],
            'options' => [
                'tag' => 'div',
                'class' => 'termin-list',
                'id' => 'termin-list',
            ],
            'pager' => [
                'firstPageLabel' => '««',
                'lastPageLabel' => '»»',
                'nextPageLabel' => false,
                'prevPageLabel' => false,
                'maxButtonCount' => 7,
            ],
        ]);?>

Вот вариант для ListView по работе с LinkPager. - может кому и пригодиться
Ответ написан
Isolution666
@Isolution666
Full-Stack Developer
А если я хочу сделать ссылку по принципу:

так было: http://домен/ru/site/reviev?page=1&per-page=3
так стало: http://домен/ru/site/reviev/1/3


что мне писать в urlManager ?

правило 'site/reviev/<page:\d+>' => 'site/reviev', работает только для get запросов, что не катит в случае с пагинацией.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы