Страница 1 из 2

Slug: использование ID vs "чистый" url

Добавлено: 2018.07.27, 23:34
GHopper
Приветсвую.

Так уж получилось, что в проекте нужно использовать SLUG. Причем это поле пользователь должен задавать руками. Отсюда вытекат большая вероятность отшибок/опечаток и желание изменить slug после его создания. Знаю два варианта решения:

1. Хранить историю для каждого slug и обрабатывать все запросы (по уже не используемым slug и по текущим)

2. Добавить в url идентификатор записи https://site/<post_id>/<slug>
<post_id> - идентификатор записи (всегда одинаковый для одной и тойже записи
<slug> - строка, которая может меняться как угодно и по факту может даже не учавствовать в поиске

Весь этот заморочь со slug используется в целях SEO-оптимизации. Какой из двух вариантов предпочтительнее для SEO и насколько критична разница?

Код: Выделить всё

https://site/19272/super_post
https://site/super_post
Может быть существует еще какой-нибудь вариант добиться результата?

Re: Slug: использование ID vs "чистый" url

Добавлено: 2018.07.28, 01:10
andku83
GHopper писал(а): 2018.07.27, 23:34 1. Хранить историю для каждого slug и обрабатывать все запросы (по уже не используемым slug и по текущим)
А разве для СЕО дубли страниц доступных по разным урлам не хуже отсутствия чпу и slug?

Re: Slug: использование ID vs "чистый" url

Добавлено: 2018.07.28, 09:23
GHopper
andku83 писал(а): 2018.07.28, 01:10
GHopper писал(а): 2018.07.27, 23:34 1. Хранить историю для каждого slug и обрабатывать все запросы (по уже не используемым slug и по текущим)
А разве для СЕО дубли страниц доступных по разным урлам не хуже отсутствия чпу и slug?
Вот именно, поэтому и создана тема. При первоначальном обсуждении с заказчиком все выглядело просто - сделать url страниц "человеческими", но при детальном рассмотрении обнаруживается много нюансов. Чтобы мне самому шишки не набивать и не переделывать все в будущем, прошу опытных разработчиков поделиться опытом своей "the best practice'

Re: Slug: использование ID vs "чистый" url

Добавлено: 2018.07.29, 22:47
yan
3 вариант https://site/<slug>-<post_id> и для устаревших слагов - переадресация с любых неверных слагов на верный

вариант "<post_id>/<slug>" портит структуру (иерархию) урлов

Re: Slug: использование ID vs "чистый" url

Добавлено: 2018.07.30, 09:39
Loveorigami
Post_id - не меняется.
Slug - меняется, причем многократно.
-------
Пишите небольшое поведение. При изменении slug-a, заносите старое название, как url, в таблицу Redirects (old_url, post_id).

Направляете обработку ошибок, в случае неверного url-a, на свой компонент

Код: Выделить всё

    'components' => [
        'errorHandler' => [
            'class' => modules\seo\components\Redirect::class,
            'errorAction' => 'site/error',
        ],
    ],
В котором делаете необходимую логику

Например

Код: Выделить всё


class Redirect extends ErrorHandler
{
    public function handleException($exception)
    {

        /** @var SeoRedirect $redirectModel */
        $redirectModel = SeoRedirect::find()
            ->where(['old_url' => Yii::$app->request->url])
            ->asArray()
            ->one();

        if (!empty($redirectModel)) {
            $redirectStatus = ($redirectModel['code']) ?: 301;
            
            $model = Post::find()->where(["post_id"=>$redirectModel['post_id']])->one();

            header("Location: " . Url::to('/post/view', ['slug'=>$model->slug]), true, $redirectStatus);
            exit;
        }

        parent::handleException($exception);
    }

}


Re: Slug: использование ID vs "чистый" url

Добавлено: 2018.07.30, 13:45
yan
Loveorigami писал(а): 2018.07.30, 09:39 Пишите небольшое поведение. При изменении slug-a, заносите старое название, как url, в таблицу Redirects (old_url, post_id).
зачем? с точки зрения сео тот слаг которой уже был, не отличается от произвольного неверного слага - на обоих д.б. переадресация на верный слаг
Loveorigami писал(а): 2018.07.30, 09:39 Направляете обработку ошибок, в случае неверного url-a, на свой компонент

Код: Выделить всё

    'components' => [
        'errorHandler' => [
            'class' => modules\seo\components\Redirect::class,
            'errorAction' => 'site/error',
        ],
    ],
с чего бы вдруг все ошибки на сайте обслуживал компонент отвечающий только за переадресацию одного типа урлов? можно просто отправлять любые слаги одного типа в экшен, там уже проверять соответствие слага и если нужно выдавать редирект

Re: Slug: использование ID vs "чистый" url

Добавлено: 2018.07.30, 14:00
Loveorigami
yan писал(а): 2018.07.30, 13:45 зачем? с точки зрения сео тот слаг которой уже был, не отличается от произвольного неверного слага - на обоих д.б. переадресация на верный слаг
Как будет происходить переадресация?

Я рассматриваю не Ваш вариант(site.ru/1-first-slug). А такой

Код: Выделить всё

site.ru/first-slug
site.ru/first-slug-for-post1
site.ru/new-slug
site.ru/last-slug
где first-slug, first-slug-for-post1, new-slug - это старые слаги поста с id = 1. А last-slug - это последний правильный.

При запросе на site.ru/first-slug, который проиндексирован, нужно с 301 редиректом перенаправить на site.ru/last-slug.
Поэтому Вы должны знать, какому id принадлежал ранее тот или иной slug.
с чего бы вдруг все ошибки на сайте обслуживал компонент отвечающий только за переадресацию одного типа урлов?
С того, что это пример, показывающий идею. Перед тем, как вывести ошибку о несуществующей странице, вначале идет запрос на поиск того, была ли эта страница ранее на этом сайте. Добавьте в модель (в моем примере это SeoRedirect) owner_class и owner_id... В чем проблема? И записывайте сюда любой тип урлов.

Если ничего не найдено в редиректах - далее parent::handleException($exception);

Re: Slug: использование ID vs "чистый" url

Добавлено: 2018.07.30, 14:38
yan
Loveorigami писал(а): 2018.07.30, 14:00
с первым согласен - не учел, отчасти поэтому не делают подобные слаги, что со временем слаг одной страницы может перекочевать под другую, что совсем не хорошо с точки зрения сео

по второму это слишком не правильно, чтобы приводить даже для примера, общий обработчик ошибок не должен быть заточен под такую узкую задачу - через него же все ошибки проходят, почему он вдруг только этими редиректами занимается?

Re: Slug: использование ID vs "чистый" url

Добавлено: 2018.07.30, 16:07
Loveorigami
с первым согласен - не учел, отчасти поэтому не делают подобные слаги, что со временем слаг одной страницы может перекочевать под другую, что совсем не хорошо с точки зрения сео
А это уже, как заказчик пожелает. Вряд ли ему захочется, чтоб страница о компании (site.ru/about) называлась site.ru/125-about
И в примере выше - не перекочевывают. А меняют slug у одной и той же записи (4 раза). И со старых трех (которые многократно проиндексированы), нужно сделать редирект (301) на единственно верный.
Так уж получилось, что в проекте нужно использовать SLUG. Причем это поле пользователь должен задавать руками. Отсюда вытекат большая вероятность отшибок/опечаток и желание изменить slug после его создания. Знаю два варианта решения:
Меняют не только после создания, а чтобы попасть в семантическое ядро. Или после разработки нового сайта с новыми путями и сохранением ссылочной массы. Причин - много...

=============
по второму это слишком не правильно, чтобы приводить даже для примера, общий обработчик ошибок не должен быть заточен под такую узкую задачу - через него же все ошибки проходят, почему он вдруг только этими редиректами занимается?
Он не занимается только ими. А занимается и ими тоже.
Он отлавливает ошибки вида - PageNotFound, и устанавливает, действительно ли это так или есть редирект.

Еще раз (с уточнением)

Код: Выделить всё

class PageController extends Controller
{
    public function actionView($slug)
    {
        $model = PageItem::find()->where(['slug' => $slug])->published()->one();

        if (!$model) {
            throw new NotFoundHttpException(\Yii::t('frontend', 'Page not found'));
        }
    }
}

class Redirect extends ErrorHandler
{
    /**
     * @param \Exception $exception
     */
    public function handleException($exception): void
    {
    
        if ($exception instanceof NotFoundHttpException) {
            /** @var SeoRedirect $redirectModel */
            $redirectModel = SeoRedirect::find()
                ->where(['old_url' => Yii::$app->request->url])
                ->asArray()
                ->one();

            if (!$redirectModel) {
                $redirectStatus = $redirectModel['code'] ?: 301;
                header('Location: ' . $redirectModel['new_url'], true, $redirectStatus);
                exit;
            }
        }

        parent::handleException($exception);
    }

}

У Вас есть другое решение?

Re: Slug: использование ID vs "чистый" url

Добавлено: 2018.07.30, 17:14
GHopper
yan писал(а): 2018.07.29, 22:47 вариант "<post_id>/<slug>" портит структуру (иерархию) урлов
насколько это критично?

Re: Slug: использование ID vs "чистый" url

Добавлено: 2018.07.30, 17:42
yan
GHopper писал(а): 2018.07.30, 17:14
yan писал(а): 2018.07.29, 22:47 вариант "<post_id>/<slug>" портит структуру (иерархию) урлов
насколько это критично?
насколько никто точно не скажет - в сео постоянно все меняется, но более правильная структура это всегда для сео хорошо, к тому же такой вид урла он явно не ЧПУ - почему два уровня папок описывают фактически один и тот же контент? что будет по урлу "<post_id>/"?
если смущает как определить тип урла по виду, лучше добавить в начало какую-то "папку" типа /posts/name-12, на уровне /posts/ хорошо встанет список постов

Re: Slug: использование ID vs "чистый" url

Добавлено: 2018.07.30, 19:08
yan
Loveorigami писал(а): 2018.07.30, 16:07 У Вас есть другое решение?
для таких целей есть стандартный функционал фреймворка - урлменеджер и https://www.yiiframework.com/doc/guide/ ... ting-rules
настраиваете в веб-сервере передачу всех несуществующих урлов в приложение (как описано в мануале) и дальше разруливаете с помощью правил урлменеджера, а ловить и обрабатывать 404 ошибки, чтобы работать с произвольными урлами (так ведь предлагаете?) уже очень давно не модно, тем более странно так делать если в применяемом фреймворке уже все есть для этого

Re: Slug: использование ID vs "чистый" url

Добавлено: 2018.07.30, 20:43
Loveorigami
С не "непроизвольными", а с теми, у которых изменился slug и страница стала недоступна по старому slug-у.
Я просто дополнил ваш пример,
3 вариант https://site/<slug>-<post_id> и для устаревших слагов - переадресация с любых неверных слагов на верный
убрав - post_id из урла.

А слуг изменится может где угодно.

Такой url manager

Код: Выделить всё

'shop/<category:[\w_-]+>/<slug:[\w_-]+>'=>'shop/product',
'shop/<category:[\w_-]+>'=>'shop/category',
'shop'=>'shop/index',

'news/<category:[\w_-]+>/<slug:[\w_-]+>'=>'news/view',
'news/<category:[\w_-]+>'=>'news/category',
'news'=>'news/index',

'<slug:[\w_-]+>'=>'page/view',

1. Я изменил slug у продукта. Получил 404
2. Я изменил slug у категории новостей. 404 у категории и 404 у всех новостей из этой категории.
3. Я изменил slug у страницы. Было site.ru/about-us, стало site.ru/about. 404 для первого сегмента.

Как будет выглядеть Ваш Url-manager?
А если у меня пару десятков модулей?

На каждый модуль писать свое правило? Делать запрос на существование слуга. Если нет - тогда запрос в редирект. Если есть - тогда перенаправляем на нужный action, и там же еще раз делаем этот же запрос.

Т.е. на любой существующий url нужно делать 2 запроса и писать свои классы правил?

Re: Slug: использование ID vs "чистый" url

Добавлено: 2018.07.30, 20:54
Loveorigami
А, кстати, как из правила делать редирект?

Re: Slug: использование ID vs "чистый" url

Добавлено: 2018.07.30, 20:58
yan
Loveorigami писал(а): 2018.07.30, 20:43 С не "непроизвольными", а с теми, у которых изменился slug и страница стала недоступна по старому slug-у.
а как в вашем варианте будут обрабатываться актуальные, не устаревшие слаги?
Loveorigami писал(а): 2018.07.30, 20:43 Как будет выглядеть Ваш Url-manager?
А если у меня пару десятков модулей?

На каждый модуль писать свое правило? Делать запрос на существование слуга. Если нет - тогда запрос в редирект. Если есть - тогда перенаправляем на нужный action, и там же еще раз делаем этот же запрос.

Т.е. на любой существующий url нужно делать 2 запроса и писать свои классы правил?
я дал ссылку, создается свое правило и там можно и запросы в базу делать и все что угодно https://www.yiiframework.com/doc/guide/ ... ting-rules

Re: Slug: использование ID vs "чистый" url

Добавлено: 2018.07.30, 20:59
yan
Loveorigami писал(а): 2018.07.30, 20:54 А, кстати, как из правила делать редирект?
редирект делается в контроллере, там ему самое подходящее место, дело правила в урлменеджере - направить на нужный экшен

Re: Slug: использование ID vs "чистый" url

Добавлено: 2018.07.30, 21:13
Loveorigami
Я прекрасно знаю эту ссылку. И у меня есть свои правила. Но не для того, чтобы в них искать старые урлы и перенаправлять на контроллер для редиректа, (который нужно еще сделать)...

У меня.
1. Изменили слуг у продукта. Поведение сделало запись в SeoRedirects.
2. Обращаюсь по старому урлу. UrlManager нашел правило

Код: Выделить всё

'shop/<category:[\w_-]+>/<slug:[\w_-]+>'=>'shop/product',
без всяких запросов и всяких классов.
3. Я в контролере с продуктом словил NotFoundHttpException и в ErrorHandler-е сделал 1 запрос и редирект. Все.
4. Не важно, откуда пришло исключение NotFoundHttpException. Главное, чтобы была запись в редиректах. Котрую я могу добавить и вручную.

У вас? Процетирую сам себя
На каждый модуль писать свое правило? Делать запрос на существование слуга. Если нет - тогда запрос в редирект. Если есть - тогда перенаправляем на нужный action, и там же еще раз делаем этот же запрос.
Вам так нравится решать эту задачу?

Re: Slug: использование ID vs "чистый" url

Добавлено: 2018.07.30, 21:22
Loveorigami
а как в вашем варианте будут обрабатываться актуальные, не устаревшие слаги?
У меня нет понятия устаревший или нет...

В который раз пишу одно и то же...
1. Зашел по урлу (slug - как часть урла).
2. UrlManger перенаправил на нужный модуль/контроллер/экшн.
3. Если модель найдена - по вашему - урл актуальный. 200
4. Если нет - NotFoundHttpException. Ищу запись в редиректе.
5. Если есть - значит урл, устаревший. 301
6. Если нет - урл не существует. 404

Re: Slug: использование ID vs "чистый" url

Добавлено: 2018.07.30, 21:26
yan
Loveorigami писал(а): 2018.07.30, 21:13 3. Я в контролере с продуктом словил NotFoundHttpException и в ErrorHandler-е сделал 1 запрос и редирект. Все.
может бросил NotFoundHttpException ? откуда он появился там? :roll:

замечу, что слаг в описанном варианте начинается сразу с корня, никаких shop

Re: Slug: использование ID vs "чистый" url

Добавлено: 2018.07.30, 21:29
yan
Loveorigami писал(а): 2018.07.30, 21:22
а как в вашем варианте будут обрабатываться актуальные, не устаревшие слаги?
У меня нет понятия устаревший или нет...

В который раз пишу одно и то же...
1. Зашел по урлу (slug - как часть урла).
2. UrlManger перенаправил на нужный модуль/контроллер/экшн.
3. Если модель найдена - по вашему - урл актуальный. 200
4. Если нет - NotFoundHttpException. Ищу запись в редиректе.
5. Если есть - значит урл, устаревший. 301
6. Если нет - урл не существует. 404
ладно закончим, чувствую мы друг-друга не понимаем, замечу только еще раз, что для сео 404 вредно, так что старый или не существующий - в любом случае дб переадресация