Yii2. Написание своего правила разбора и построения url
Во всех веб-приложениях, ориентированных на СЕО, невозможно обойтись без реализации ЧПУ. Сегодня я расскажу о том как реализовать произвольный класс построения и разбора url
в Yii framework 2
.
Допустим у нас есть ActiveRecord-модель Page со следующими полями
id
- идентификатор записиparent_id
- идентификатор родителяslug
- последняя часть урлurl
- полный урл без слешей в начале и конце, который формируется как url родителя + '/' + url текущей записиname
- название страницыcontent
- контент страницыactive
- страница активна?
Именно для этой модели мы и будем писать правило разбора. Для этого нам необходимо реализовать интерфейс yii\web\UrlRuleInterface
- это всего два метода: createUrl
и parseRequest
. Метод создания урл и его разбора соответственно.
Создадим класс-заглушку с пустыми методами
class PageRule implements UrlRuleInterface { public function createUrl($manager, $route, $params){} public function parseRequest($manager, $request){} }
И добавим его в список правил урл-менеджера конфигурации веб-приложения.
'components' => [ 'urlManager' => [ 'rules' => [ // other rules [ 'class' => \app\components\PageRule::class, ], // other rules ], ], ],
Начнем с написания кода построения урл по id записи. Ниже представлен готовый код с комментариями.
public function createUrl($manager, $route, $params) { if ($route !== 'page/show' || isset($params['id']) === false) { // проверяем, что это маршрут для страницы и нам передали id-записи return false; // return false сообщает UrlManager-у, что мы не смогли построить url и необходимо попробовать применить следующее правило } $slug = Page::find() // тут все просто. Это поиск записи в БД. ->select('url') ->where( [ 'id' => $params['id'], 'active' => 1, ] ) ->scalar(); if ($slug !== false) { // если поиск увенчался успехом, то неободимо вернуть найденный урл return '/' . $slug; // слеш в начале дает знать, что это абсолютный url } return false; // мы ничего не нашли в БД :( }
Отлично. Мы научились строить ссылки. Для этого достаточно вызвать yii\helpers\Url::toRoute(['/page/show', 'id' => 5])
и мы получим url, если в БД присутствует необходимая страница и она активна.
С парсингом url тоже нет проблем. Разберем код.
public function parseRequest($manager, $request) { $url = trim($request->pathInfo, '/'); // удаляем слеши из начала и конца url $page = Page::find() // ищем запись по url ->where( [ 'url' => $url, 'active' => 1, ] ) ->one(); if ($page !== null) { // если нашли, то передаем данные в PageController::actionShow($id). В нем будем рендерить страницу return ['page/show', ['id' => $page->id]]; } return false; // сообщаем UrlManager, что ничего не нащли и необходимо попробовать применит следующее правило }
Вот и все. Как видите, реализовать разбор и построение ЧПУ в Yii2 не так уж и сложно.
P.S. Хочу обратить внимание, что данный пример не учитывает никаких дополнительных GET-параметров при разборе и построении url.