WooCommerce Transliterate Slugs | Cododel
CODODELDEV
EN / RU
Back to Deck
[snippet]

WooCommerce Transliterate Slugs

ИСХОДНИК PHP
ВЕРСИЯ 1.0
АВТОР Cododel

PHP сниппет для одноразового выполнения в WordPress/WooCommerce, который транслитерирует кириллические slugs атрибутов и терминов в латиницу. Сохраняет оригинальные отображаемые имена, исправляя только URL-небезопасные slugs.

Проблема

WooCommerce атрибуты и термины с кириллическими названиями создают URL-небезопасные slugs:

  • Атрибут: pa_цвет → Должно быть pa_cvet
  • Термин: красный → Должно быть krasnyj

Это вызывает проблемы с:

  • SEO (не-латинские URL)
  • Кодировка URL
  • Индексация базы данных
  • Совместимость с API

⚠️ Важные предупреждения

  1. СДЕЛАЙТЕ БЭКАП БАЗЫ ДАННЫХ перед запуском скрипта
  2. Это сниппет одноразового выполнения
  3. Он модифицирует базу данных напрямую
  4. Удалите код после выполнения
  5. Тестируйте на staging окружении сначала

Возможности

  • ✅ Транслитерирует кириллицу в латиницу для slugs атрибутов
  • ✅ Обновляет slugs терминов, сохраняя имена
  • ✅ Одноразовое выполнение с проверкой опции
  • ✅ Правильное использование WooCommerce API
  • ✅ Инвалидация кеша
  • ✅ Логирование ошибок

Инструкция по использованию

  1. Бэкап базы данных:

    Terminal window
    # Через wp-cli
    wp db export backup.sql
  2. Добавить в functions.php:

    // Добавьте весь код ниже в functions.php вашей темы
  3. Загрузите любую страницу на вашем WordPress сайте для запуска

  4. Проверьте результаты:

    • Проверьте WooCommerce → Атрибуты
    • Проверьте URL атрибутов товаров
  5. Удалите код из functions.php после выполнения

Примеры трансформаций

ДоПосле
pa_цветpa_cvet
pa_размерpa_razmer
красныйkrasnyj
большойbolshoy

Исходный код

update-wc-attributes-terms-slugs.php

<?php
function update_woocommerce_attributes_and_terms() {
// Получаем все атрибуты WooCommerce
$attributes = wc_get_attribute_taxonomies();
if (empty($attributes)) {
return;
}
foreach ($attributes as $attribute) {
$old_taxonomy = wc_attribute_taxonomy_name($attribute->attribute_name);
$new_attribute_name = cyr_to_lat_sanitize($attribute->attribute_name);
$new_taxonomy = wc_attribute_taxonomy_name($new_attribute_name);
// Если slug атрибута нужно обновить
if ($new_attribute_name !== $attribute->attribute_name) {
// Обновляем атрибут через WooCommerce
$attribute_data = [
'id' => $attribute->attribute_id,
'name' => $attribute->attribute_label, // Оставляем оригинальное название
'slug' => $new_attribute_name,
'type' => $attribute->attribute_type,
'order_by' => $attribute->attribute_orderby,
'has_archives' => $attribute->attribute_public
];
$result = wc_update_attribute($attribute->attribute_id, $attribute_data);
if (is_wp_error($result)) {
error_log("Failed to update attribute {$attribute->attribute_name}: " . $result->get_error_message());
continue;
}
// Обновляем термины для старой таксономии
$terms = get_terms([
'taxonomy' => $old_taxonomy,
'hide_empty' => false,
]);
if (!is_wp_error($terms)) {
foreach ($terms as $term) {
$new_term_slug = cyr_to_lat_sanitize($term->slug);
if ($new_term_slug !== $term->slug) {
wp_update_term($term->term_id, $new_taxonomy, [
'slug' => $new_term_slug,
// Название термина не меняем
]);
}
}
}
// Удаляем старую таксономию и регистрируем новую
unregister_taxonomy($old_taxonomy);
register_taxonomy(
$new_taxonomy,
'product',
[
'label' => $attribute->attribute_label,
'public' => (bool) $attribute->attribute_public,
'hierarchical' => false,
'show_ui' => false,
]
);
}
// Обновляем slug терминов даже если атрибут не менялся
$terms = get_terms([
'taxonomy' => $new_taxonomy,
'hide_empty' => false,
]);
if (!is_wp_error($terms)) {
foreach ($terms as $term) {
$new_term_slug = cyr_to_lat_sanitize($term->slug);
if ($new_term_slug !== $term->slug) {
wp_update_term($term->term_id, $new_taxonomy, [
'slug' => $new_term_slug,
// Название термина не меняем
]);
}
}
}
}
// Очищаем кэш
delete_transient('wc_attribute_taxonomies');
WC_Cache_Helper::invalidate_cache_group('woocommerce-attributes');
wp_cache_flush();
}
// Выполняем один раз
add_action('init', function() {
if (get_option('update_wc_attributes_and_terms') !== 'done') {
update_woocommerce_attributes_and_terms();
update_option('update_wc_attributes_and_terms', 'done');
}
});
// Функция транслитерации
function cyr_to_lat_sanitize($text) {
$cyr = [
'а'=>'a', 'б'=>'b', 'в'=>'v', 'г'=>'g', 'д'=>'d', 'е'=>'e', 'ё'=>'yo', 'ж'=>'zh',
'з'=>'z', 'и'=>'i', 'й'=>'y', 'к'=>'k', 'л'=>'l', 'м'=>'m', 'н'=>'n', 'о'=>'o',
'п'=>'p', 'р'=>'r', 'с'=>'s', 'т'=>'t', 'у'=>'u', 'ф'=>'f', 'х'=>'h', 'ц'=>'ts',
'ч'=>'ch', 'ш'=>'sh', 'щ'=>'sht', 'ъ'=>'', 'ы'=>'y', 'ь'=>'', 'э'=>'e', 'ю'=>'yu',
'я'=>'ya',
'А'=>'A', 'Б'=>'B', 'В'=>'V', 'Г'=>'G', 'Д'=>'D', 'Е'=>'E', 'Ё'=>'Yo', 'Ж'=>'Zh',
'З'=>'Z', 'И'=>'I', 'Й'=>'Y', 'К'=>'K', 'Л'=>'L', 'М'=>'M', 'Н'=>'N', 'О'=>'O',
'П'=>'P', 'Р'=>'R', 'С'=>'S', 'Т'=>'T', 'У'=>'U', 'Ф'=>'F', 'Х'=>'H', 'Ц'=>'Ts',
'Ч'=>'Ch', 'Ш'=>'Sh', 'Щ'=>'Sht', 'Ъ'=>'', 'Ы'=>'Y', 'Ь'=>'', 'Э'=>'E', 'Ю'=>'Yu',
'Я'=>'Ya'
];
$text = strtr($text, $cyr);
$text = preg_replace('/[^a-zA-Z0-9\s-]/', '', $text);
return sanitize_title(trim($text));
}
[ ▲ 0 ]