SEO-дружественные URL-адреса в рамках YII с идентификатором и именем

Я искал все форумы Stackoverflow и YII, есть много ответов, которые мне не помогли...

Это мой случай.

У меня есть контроллер с именем: proj и действие с именем view. Он получает: id(int), name(string).

Желаемое имя иногда получает специальные символы, такие как: [+,!#$%^&*-]

Поэтому, когда я запускаю функцию createUrl(), она возвращает мне не очень удобный URL-адрес.

Например: http://www.qa-mysite.com/proj/1029/Conservation+of+the+Vermont+Salt+Pan+System%2C+Hermanus%2C+Юг+Африка.

id = 1029 name = Сохранение системы солончаков Вермонта, Херманус, Южная Африка.

Я хочу, чтобы результат был следующим: http://www.qa-mysite.com/proj/1029/conservation-of-the-vermont-salt-pan-system-hermanus-south-Africa

Так что на самом деле мне нужно убрать специальные символы и изменить разделитель между пробелами на «-» вместо «+».

Мои текущие конфигурации curlManager:

'urlManager'=>array(
            'urlFormat'=>'path',
            'showScriptName'=>false,
            'appendParams' => true,
            'rules'=>array(
            //array('proj/view/<name:\w+>', 'pattern'=>'proj/<id:\d+>'),
                //'<controller:\w+>/<id:\d+>'=>'<controller>/view',
                'proj/<id:\d+>/<name:\w+>'=>array('proj/view', 'caseSensitive'=>false),
                '<controller>/<id:\d+>/<name:.*?>'=>'<controller>/view',
                '<controller:\w+>/<action:\w+>/<id:\d+>'=>'<controller>/<action>',
                '<controller:\w+>/<action:\w+>'=>'<controller>/<action>',
            ),
        )

Пример CreateUrl:

$this->createUrl('proj/view', array('id' => $data->id, 'name' => $data->name));

После того, как URL-адреса будут изменены, мне нужно сделать 301 переадресацию со старых на новые, оптимизированные для SEO.

Примечание. Я не могу сделать жестко запрограммированный файл str_replace.

Большое спасибо за любую помощь:]


person Michael Kisilenko    schedule 18.09.2013    source источник


Ответы (3)


Создайте свой собственный менеджер URL-адресов, создав подкласс CUrlManager и немного ovveride createUrl, например:

class MyUrlManager extends CUrlManager {
    public function createUrl($route,$params=array(),$ampersand='&') {
        if($route == 'proj/view' && isset($params['name'])) {
            $params['name'] = processYourParamFunction($params['name']);
        }
        return parent::createUrl($route,$params,$ampersand);
    }
}

Затем измените свою конфигурацию, чтобы использовать этот класс:

...
'urlManager' => [
    'class' => 'MyUrlManager'
...
]

Это одна из замечательных функций Yii, естественная инверсия управления :)

Для второй части вопроса:

При просмотре действия просто перенаправьте на новый URL-адрес с помощью createurl, если вы обнаружите нежелательные символы. Просто убедитесь, что вы не попали в цикл перенаправления.

Обновление:

Чтобы перенаправить с помощью 301, просто передайте код перенаправления третьим параметром для перенаправления вызова:

$this->redirect('route', true, 301);

Примечание:

Используйте cannonical, чтобы указать поисковым системам правильный URL.

person Community    schedule 18.09.2013
comment
TNX :] Я хочу, чтобы старые URL-адреса были доступны, и когда вы их вводите, сервер формирует 301. - person Michael Kisilenko; 19.09.2013

Прежде всего, ответ PeterM хороший, это хороший подход.

Я сделал это по-другому.

Я создал помощник под названием "TextHelper" с одной статической функцией:

class TextHelper{
    public static function cleanText($text=""){
        $text = preg_replace('/[^A-Z0-9]+/i', '-', $text);
        $text = strtolower(trim($text, '-'));

        return $text;
    }
}

И изменил createUrl(), чтобы он очищался с помощью cleanText(), например:

$this->createUrl('proj/view', array('id' => $proj->id, 'name' => TextHelper::getSlug($proj->name)));

Наконец, мой config/main.php:

'urlManager'=>array(
            'urlFormat'=>'path',
            'showScriptName'=>false,
            'appendParams' => true,
            'rules'=>array(
                'proj/<id:\d+>/<name:\w+>'=>array('proj/view', 'caseSensitive'=>false),
                '<controller>/<id:\d+>/<name:.*?>'=>'<controller>/view',
                '<controller:\w+>/<action:\w+>/<id:\d+>'=>'<controller>/<action>',
                '<controller:\w+>/<action:\w+>'=>'<controller>/<action>',
            ),
        )

Это решение помогло мне. Надеюсь, это будет простое и эффективное решение для других разработчиков, которым необходимо столкнуться с этой проблемой.

person Michael Kisilenko    schedule 19.09.2013
comment
Также можно хранить эти слаги в БД и сбрасывать идентификатор все вместе (еще более приятные URL-адреса). - person Eirik Hoem; 10.10.2013

Это решение помогло мне. Надеюсь, это будет простое и эффективное решение для других разработчиков, которым необходимо столкнуться с этой проблемой.

'urlManager'=>array(
                'urlFormat'=>'path',
                'showScriptName'=>false,
                'appendParams' => true,
                'rules'=>array(
                    'proj/<id:\d+>/<name:\w+>'=>array('proj/view', 'caseSensitive'=>false),
                    '<controller>/<id:\d+>/<name:.*?>'=>'<controller>/view',
                    '<controller:\w+>/<action:\w+>/<id:\d+>'=>'<controller>/<action>',
                    '<controller:\w+>/<action:\w+>'=>'<controller>/<action>',
                ),
            )
person intexbenq    schedule 27.12.2013