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
⚠️ Важные предупреждения
- СДЕЛАЙТЕ БЭКАП БАЗЫ ДАННЫХ перед запуском скрипта
- Это сниппет одноразового выполнения
- Он модифицирует базу данных напрямую
- Удалите код после выполнения
- Тестируйте на staging окружении сначала
Возможности
- ✅ Транслитерирует кириллицу в латиницу для slugs атрибутов
- ✅ Обновляет slugs терминов, сохраняя имена
- ✅ Одноразовое выполнение с проверкой опции
- ✅ Правильное использование WooCommerce API
- ✅ Инвалидация кеша
- ✅ Логирование ошибок
Инструкция по использованию
-
Бэкап базы данных:
Terminal window # Через wp-cliwp db export backup.sql -
Добавить в
functions.php:// Добавьте весь код ниже в functions.php вашей темы -
Загрузите любую страницу на вашем WordPress сайте для запуска
-
Проверьте результаты:
- Проверьте WooCommerce → Атрибуты
- Проверьте URL атрибутов товаров
-
Удалите код из
functions.phpпосле выполнения
Примеры трансформаций
| До | После |
|---|---|
pa_цвет | pa_cvet |
pa_размер | pa_razmer |
красный | krasnyj |
большой | bolshoy |
Исходный код
update-wc-attributes-terms-slugs.php
<?phpfunction 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));}