Yii и ЧПУ для каталога
Дано: сайт с каталогом продукции.
Для общего развития - очень полезная статья в мануале, откуда я все и почерпнула.
UPDATED
Данный класс размещаем в папке components. И настраиваем конфиг. Так выглядит конфиг у меня:
Необходимо: реализовать url вида http://site.ru/marka/model, а иначе говоря /Производитель/Модель.
Решение:
Правило для URL вида /Производитель/Модель добавляем в параметр urlManager (приоритет, т.е. в начало или конец массива, определите сами).
array(
'class' => 'application.components.CatalogRule',
'connectionID' => 'db',
),
// стандартные правила для обработки 'post/update' и др.
'<controller: w="">/<action: w="">' => '<controller>/<action>',
// ...
),
Класс CatalogUrl
class CatalogRule extends CBaseUrlRule
{
public $connectionID = 'db';
public function createUrl($manager,$route,$params,$ampersand) {
if ($route==='catalog/index') {
if (isset($params['mark'], $params['model']))
return $params['mark'] . '/' . $params['model'];
else if (isset($params['mark']))
return $params['mark'];
}
return false; // не применяем данное правило
}
public function parseUrl($manager,$request,$pathInfo,$rawPathInfo) {
if (preg_match('%^(\w+)(/(\w+))?$%', $pathInfo, $matches)) {
// Проверяем $matches[1] и $matches[3] на предмет
// соответствия производителю и модели в БД.
$mark = CatalogMark::model()->find('alias=:alias', array(':alias' => $matches[1]));
if ($mark !== null) {
$_GET['mark'] = $mark->id;
$model = CatalogModel::model()->getByAlias($matches[3], $mark->id);
if($model !== null) {
$_GET['model'] = $model->id;
}
// Если соответствуют, выставляем $_GET и возвращаем строку с маршрутом 'catalog/index'.
return 'catalog/index';
}
}
return false; // не применяем данное правило
}
}
Свой класс Url обязательно должен реализовать методы createUrl и parseUrl. Приведенный выше пример используется на одном из реализованных мной проектов. Хотя сейчас он претерпел некоторые изменения и оброс дополнительными условиями :)Для общего развития - очень полезная статья в мануале, откуда я все и почерпнула.
UPDATED
Данный класс размещаем в папке components. И настраиваем конфиг. Так выглядит конфиг у меня:
'urlManager' => array(
'urlSuffix' => '/',
'showScriptName' => false,
'urlFormat' => 'path',
'rules' => array(
'http://<domain: w+>.site.ru/' => 'site/index',
array(
'class' => 'application.components.CatalogRule',
'connectionID' => 'db',
),
'<controller: w+>/<id: d+>'=>'<controller>/view',
'<controller: w+>/<action: w+>/<id: d+>'=>'<controller>/',
'<controller: w+>/<action: w+>'=>'<controller>/<action>',
'<module: w+>/<controller: w+>/<action: w+>/<id: d+>' => '<module>/<controller>/<action>',
'<module: w+>/<controller: w+>/<action: w+>' => '<module>/<controller>/<action>',
'<module: w+>/<controller: w+>' => '<module>/<controller>/index',
),
),
Спасибо!!!
ОтветитьУдалитьДоброго дня.
ОтветитьУдалитьА как вы используете далее созданный класс для создания и разбора url? У меня получилось через добавления кода в файле CWebApplication.php в фу-цию processRequest
$cat_rule = new CatalogRule();
$route = $cat_rule->parseUrl('', '', $route, '');
Насколько это правильно есть другие способы?
это неправильно править файлы фреймворка.
УдалитьНаш класс - это компонент. Помещаете его в папку components. И в конфигах указываете, когда следует его применять в секции urlManager. Дополнила пост примером своего конфига.
В конфиге "urlManager" объявление класса в разделе "rules" было после стандартных правил поставил перед ними и заработало.
ОтветитьУдалитьВсе верно. Ведь как только находится совпадение с правилом, остальные правила не отрабатывают. Поэтому наше правило стоит раньше в списке
УдалитьСпасибо! Теперь полная картина :)
ОтветитьУдалитьЗдравствуйте!
ОтветитьУдалитьНе могу разобрать такое url /investment-and-business/e-commerce/kredit-v-sisteme-yandeks-dengi, если Вам не сложно подскажите пожалуйста!
я не особо сильна в регулярных выражениях. Погуглите регулярку для вашего урл, думаю, в сети уже есть масса примеров
УдалитьНачал изучение yii2. Возникла подобная задача. С пониманием у меня туго. Перерыл массу всего, но этот пример оказался для меня наиболее удачным! =)
ОтветитьУдалитьЛучей добра и счастья автору! <3
спасибо ) и вам добра ;)
УдалитьЭтот комментарий был удален автором.
ОтветитьУдалитьа как быть с пагинацией? у меня валятся все правила
ОтветитьУдалитьтакже нужно переписать правила и пагинации, и сортировки.
УдалитьКак пример, для вывода новостей у меня был использован CListView. Для него задаем параметр
'pager'=>array('class'=>'Pager', 'pageVar' => 'News_page'),
И класс Pager здесь - это наследник класса CLinkPager с переписанным методом createPageUrl
круто! спасибо! остается еще один вопрос. есть форма поиска(вернее фильтрации) ну вроде выбрать марку, потом модель. как переопределить createUrl для формы? форма сделана через CActiveForm, соответственно данные приходят в виде ?modelName model=xxx&.... ну вы понимаете о чем я. сейчас у меня один вариант - сделать экшен, который будет принимать дагнную форму и редиректить с правильным create url, но похоже на костыл какой-то.
Удалитьhttp://www.yiiframework.com/doc/api/1.1/CActiveForm#action-detail
Удалитьочевидно, вы про это
Вопрос не совсем по этой теме, но мне некуда больше пойти. Я нигде не нашел выхода. Спасите. У меня есть ссылка domen.ru/index.php/site/cars/1
ОтветитьУдалитьcreateurl работает и не ставит index.php но если ручками набрать ссылка прекрасно работает. но мне нужен редирект с нее на domen.ru/cars/1
в htaccess
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php
в сonfige
'urlManager'=>array(
'urlFormat' => 'path',
'showScriptName'=>false,
'rules'=>array(
'' => 'site/index',
'' => 'site/',
array(
'class' => 'application.components.CarsRule',
'connectionID' => 'db',
),
),
),
Что не так?? подскажите, буду должен..
Если необходим именно редирект с подменой адреса в строке браузера, то только htaccess по правилу
УдалитьВопрос лишь в том, точно ли нужен редирект, возможно, нужно сделать так, чтобы ссылки формировались правильные и необходимость редиректа отпадет. Кстати, очень странный формат ссылки domen.ru/index.php/site/cars/1