Перегенерация пермалинков (слагов) — массовое изменение ЧПУ на сайте WordPress

Задача — настроить ЧПУ, чтобы вместо post_id использовался postname.

Проблема — после изменения настроек постоянных ссылок на сайте сгенерированы ЧПУ неправильно, еще на сайте настроена мультиязычность с помощью плагина Polylang, и в Рус версии урлы обрезаются на половине слова, а в Укр версии слаги проставлены как post_id .

Совет — для начала попробуйте плагин Cyr-To-Lat — у него в настройках есть замечательная функция Конвертер, с помощью которого можно сконвертировать свои пермалинки с возможностью транслитерации, но в моем случае это не сработало, думаю, что в 90% это вариант будет рабочим и более простым.

Решение проблемы — установка плагина Regenerate post permalink с доработками. Поскольку плагин не поддерживается уже на протяжении 5 лет и нам он нужен на один раз, а других плагинов для решения данной задачи нет, тогда можем смело внести необходимые нам исправления прям в плагин и после решения задачи просто удалить его.

Вносим изменения в файл regenerate-post-permalink.php — он там в принципе единственный.

1. Меняем таблицу транслитерации для кириллицы с укр. языком на такую:

$table = array( 'А' => 'A', 'Б' => 'B', 'В' => 'V', 'Г' => 'G', 'Ґ' => 'G', 'Д' => 'D', 'Е' => 'E', 'Ё' => 'YO', 'Є' => 'YE', 'Ж' => 'ZH', 'З' => 'Z', 'И' => 'Y', 'І' => 'I', 'Ї' => 'YI', 'Й' => 'J', 'К' => 'K', 'Л' => 'L', 'М' => 'M', 'Н' => 'N', 'О' => 'O', 'П' => 'P', 'Р' => 'R', 'С' => 'S', 'Т' => 'T', 'У' => 'U', 'Ф' => 'F', 'Х' => 'H', 'Ц' => 'CZ', 'Ч' => 'CH', 'Ш' => 'SH', 'Щ' => 'SHH', 'Ь' => '', 'Ъ' => '', 'Ю' => 'YU', 'Я' => 'YA', 'а' => 'a', 'б' => 'b', 'в' => 'v', 'г' => 'g', 'ґ' => 'g', 'д' => 'd', 'е' => 'e', 'ё' => 'yo', 'є' => 'ye', 'ж' => 'zh', 'з' => 'z', 'и' => 'y', 'і' => 'i', 'ї' => 'yi', 'й' => 'j', 'к' => 'k', 'л' => 'l', 'м' => 'm', 'н' => 'n', 'о' => 'o', 'п' => 'p', 'р' => 'r', 'с' => 's', 'т' => 't', 'у' => 'u', 'ф' => 'f', 'х' => 'h', 'ц' => 'cz', 'ч' => 'ch', 'ш' => 'sh', 'щ' => 'shh', 'ь' => '', 'ъ' => '', 'ю' => 'yu', 'я' => 'ya', 'Ы' => 'Y', 'Э' => 'E', 'ы' => 'y', 'э' => 'e', '«' => '', '»' => '' );

2. Полностью заменяем функцию regenerate_post_permalink()

Старый код:

function regenerate_post_permalink($post_type = 'post') {
    global $wpdb;

    $myrows = $wpdb->get_results("SELECT id, post_title FROM $wpdb->posts WHERE post_status = 'publish' AND post_type='$post_type' ");
    $counter = 0;
    foreach ($myrows as $pid) :
        $post_title = regenerate_post_clear_diacritics($pid->post_title);
        $guid = home_url() . '/' . sanitize_title_with_dashes($post_title);
        $sql = "UPDATE $wpdb->posts 
                     SET post_name = '" . sanitize_title_with_dashes($post_title) . "',
                         guid = '" . $guid . "'
               WHERE ID = $pid->id";
        $wpdb->query($sql);
        $counter++;
    endforeach;

    return $counter;
}

Нам нужно выполнить проверку на дубли слагов, иначе плагин может сформировать с одинаковых заголовков одинаковые урлы:

$post_title = sanitize_title_with_dashes($post_title);
$new_slug = wp_unique_post_slug($post_title, $pid->id, 'publish', $post_type, $pid->post_parent);

Поскольку я знаю ,что у меня в постах нет вложенности, то я вместо параметра $pid->post_parent передаю 0. Для своего случая задавайте нужный параметр.

Важно: Так же нам не нужно менять guid — он должен оставаться в старом формате.

Новый код функции regenerate_post_permalink():

function regenerate_post_permalink($post_type = 'post') {
    global $wpdb;

    $myrows = $wpdb->get_results("SELECT id, post_title FROM $wpdb->posts WHERE post_status = 'publish' AND post_type='$post_type' ");
    $counter = 0;
    foreach ($myrows as $pid) :
        $post_title = regenerate_post_clear_diacritics($pid->post_title);
        $post_title = sanitize_title_with_dashes($post_title);
        $new_slug = wp_unique_post_slug($post_title, $pid->id, 'publish', $post_type, 0);
        $sql = "UPDATE $wpdb->posts SET post_name = '" . $new_slug . "' WHERE ID = $pid->id";
        $wpdb->query($sql);
        $counter++;
    endforeach;

    return $counter;
}

Затем переходим в настройки -> Permalinks regeneration -> выбираем Posts -> жмем Regenerate permalinks.

Получаем красивые урлы у всех записей и на украинском языке, и на русском.

P.S. Пока искал разные варианты решения проблемы перепробовал кучу плагинов и пересмотрел кучу блогов зарубежных. Как же надоели копирайтеры и бестолковые контентщики. Ищешь ответ на конкретный вопрос «как массово переконвертировать пермалинки» и находишь кучу статей на 5-6-7 экранов, в которых описано что такое пермалинки, зачем, почему, как их настраивать, как делать 301 редиректы, как оптимизировать для Гугла и тд, а ответа на вопрос просто нету, зато куча теории и воды… Достали контентщики, которые работают ради количества символов, а не ради решения вопросов, которые указаны в заголовке статьи. «Выговорился».

Как выводить кастомные типы записей в поиске

По умолчанию WordPress не включает пользовательские типы записей в результаты поиска. Из-за этого вам нужно самостоятельно…

Как выводить кастомные типы записей в стандартных рубриках или тегах

По умолчанию WordPress не включает кастомные типы записей в архивы категорий и тегов. Из-за этого вам…

Как исправить ошибку 404 при постраничной навигации, если используются кастомные ссылки для записей и категорий в CMS WordPress

Итак, суть проблемы — при переходе на 2-3 и так далее страницы блога возникает 404…

Как заменить пагинацию WooCommerce на WP-PageNavi

Простой способ подключить вместо стандартной пагинации WooCommerce woocommerce_pagination пагинацию с помощью плагина WP-PageNavi. Устанавливаем и…

2 комментария

Сергей Кизим

Спасибо за наводку! Я сейчас как раз тоже озаботился массовой сменой урлов на сайте.

По последнему пункту (P.S.) могу сказать, что сейчас стало всё еще хуже. Теперь пустопорожние темы пишет ChatGPT, а людям приходится их читать в поисках решения ))

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

Ответить