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

Темы, не касающиеся фреймворка, но относящиеся к программированию в целом.
GHopper
Сообщения: 83
Зарегистрирован: 2017.06.05, 10:53

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

Сообщение 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
Может быть существует еще какой-нибудь вариант добиться результата?
andku83
Сообщения: 988
Зарегистрирован: 2016.07.01, 10:24
Откуда: Харьков

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

Сообщение andku83 »

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

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

Сообщение GHopper »

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

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

Сообщение yan »

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

вариант "<post_id>/<slug>" портит структуру (иерархию) урлов
Последний раз редактировалось yan 2018.07.30, 13:37, всего редактировалось 1 раз.
Loveorigami
Сообщения: 977
Зарегистрирован: 2014.08.27, 21:54

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

Сообщение 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);
    }

}

yan
Сообщения: 942
Зарегистрирован: 2011.03.23, 09:28
Откуда: Уфа

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

Сообщение 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',
        ],
    ],
с чего бы вдруг все ошибки на сайте обслуживал компонент отвечающий только за переадресацию одного типа урлов? можно просто отправлять любые слаги одного типа в экшен, там уже проверять соответствие слага и если нужно выдавать редирект
Loveorigami
Сообщения: 977
Зарегистрирован: 2014.08.27, 21:54

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

Сообщение 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);
yan
Сообщения: 942
Зарегистрирован: 2011.03.23, 09:28
Откуда: Уфа

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

Сообщение yan »

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

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

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

Сообщение 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);
    }

}

У Вас есть другое решение?
GHopper
Сообщения: 83
Зарегистрирован: 2017.06.05, 10:53

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

Сообщение GHopper »

yan писал(а): 2018.07.29, 22:47 вариант "<post_id>/<slug>" портит структуру (иерархию) урлов
насколько это критично?
yan
Сообщения: 942
Зарегистрирован: 2011.03.23, 09:28
Откуда: Уфа

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

Сообщение yan »

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

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

Сообщение yan »

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

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

Сообщение 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 запроса и писать свои классы правил?
Loveorigami
Сообщения: 977
Зарегистрирован: 2014.08.27, 21:54

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

Сообщение Loveorigami »

А, кстати, как из правила делать редирект?
yan
Сообщения: 942
Зарегистрирован: 2011.03.23, 09:28
Откуда: Уфа

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

Сообщение 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
Последний раз редактировалось yan 2018.07.30, 21:00, всего редактировалось 2 раза.
yan
Сообщения: 942
Зарегистрирован: 2011.03.23, 09:28
Откуда: Уфа

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

Сообщение yan »

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

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

Сообщение Loveorigami »

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

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

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

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

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

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

Сообщение Loveorigami »

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

В который раз пишу одно и то же...
1. Зашел по урлу (slug - как часть урла).
2. UrlManger перенаправил на нужный модуль/контроллер/экшн.
3. Если модель найдена - по вашему - урл актуальный. 200
4. Если нет - NotFoundHttpException. Ищу запись в редиректе.
5. Если есть - значит урл, устаревший. 301
6. Если нет - урл не существует. 404
Последний раз редактировалось Loveorigami 2018.07.30, 21:27, всего редактировалось 1 раз.
yan
Сообщения: 942
Зарегистрирован: 2011.03.23, 09:28
Откуда: Уфа

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

Сообщение yan »

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

замечу, что слаг в описанном варианте начинается сразу с корня, никаких shop
yan
Сообщения: 942
Зарегистрирован: 2011.03.23, 09:28
Откуда: Уфа

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

Сообщение yan »

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

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