Недавно я столкнулся с задачей переноса сайта с Joomla K2 (vizator.ru
) на новую Joomla (jedig.ru
). Главной целью было настроить переадресацию старых URL на новые, чтобы сохранить SEO и удобство для пользователей. Процесс оказался не таким простым, как я ожидал, но в итоге всё заработало. Делюсь своим опытом и рассказываю, на что стоит обратить внимание.
С чего всё началось
На старом сайте использовалась Joomla с компонентом K2, а URL имели вид https://vizator.ru/category/alias
(например, https://vizator.ru/cooling-heating/proverka-klapanov-kryshki-rasshiritelnogo-bachka
). Новый сайт на Joomla использует структуру http://jedig.ru/cars/id-alias
(например, http://jedig.ru/cars/645-proverka-klapanov-kryshki-rasshiritelnogo-bachka
). Задача — сделать 301-редирект со старых URL на новые.
Я начал с составления списка соответствий (94 записи) и попытался настроить переадресацию через файл .htaccess
. Но первые попытки провалились — вместо редиректов я получал 404 ошибки.
Проблемы и их решение
1. Ошибка в структуре URL
Изначально я предположил, что старые URL содержат ID K2, например, cooling-heating/1-proverka-klapanov-kryshki-rasshiritelnogo-bachka
. Написал правила в .htaccess
с учётом этого:
RewriteRule ^cooling-heating/1-proverka-klapanov-kryshki-rasshiritelnogo-bachka$ http://jedig.ru/cars/645-proverka-klapanov-kryshki-rasshiritelnogo-bachka [R=301,L]
Тест показал, что такие URL работают, но внутренние ссылки на сайте были без ID (cooling-heating/proverka-klapanov-kryshki-rasshiritelnogo-bachka
), и они вели на 404. Пришлось переписать все правила под реальную структуру.
2. Проверка mod_rewrite
Когда переадресация не работала даже с правильными URL, я заподозрил, что проблема в сервере. Проверил с помощью простого теста:
RewriteEngine On RewriteBase / RewriteRule ^test$ http://jedig.ru [R=301,L]
Переход на https://vizator.ru/test
перенаправил на http://jedig.ru
, значит, mod_rewrite
активен. Если бы не сработало, пришлось бы включить модуль командой sudo a2enmod rewrite
и перезапустить Apache (sudo systemctl restart apache2
).
3. Конфликт условий в .htaccess
В первом варианте файла я добавил условия для пропуска новых страниц:
RewriteCond %{REQUEST_URI} !^cooling-heating/ [NC] RewriteCond %{REQUEST_URI} !^engine/ [NC] RewriteRule ^ - [L]
Но они блокировали переадресацию, потому что применялись ко всем запросам, включая старые URL. Исправил, объединив категории в одно условие:
RewriteCond %{REQUEST_URI} !^(cooling-heating|engine|body-chassis)/ [NC] RewriteRule ^ - [L]
Итоговый .htaccess
После всех правок получился рабочий файл, который учитывает внутренние ссылки без ID K2:
RewriteEngine On RewriteBase / RewriteRule ^cooling-heating/proverka-klapanov-kryshki-rasshiritelnogo-bachka$ http://jedig.ru/cars/645-proverka-klapanov-kryshki-rasshiritelnogo-bachka [R=301,L] RewriteRule ^engine/disel-engine-td5-base-manual$ http://jedig.ru/cars/646-disel-engine-td5-base-manual [R=301,L] # ... (остальные правила) RewriteCond %{REQUEST_URI} !^(cooling-heating|engine|body-chassis|lubricants-cleaners|general-information|pages|body-electrics|axles-suspension|gearbox-clutch-transfer-gearbox|fuel-emission-systems|tuning|vnedorozhnyj-pritsep)/ [NC] RewriteRule ^ - [L]
На что обратить внимание
- Точная структура URL: Проверьте, как выглядят реальные ссылки на сайте и в поисковиках. У меня они отличались от ожидаемых (без ID), и это вызвало путаницу.
- Работа mod_rewrite: Убедитесь, что модуль включён, иначе
.htaccess
будет игнорироваться. Используйте тестовое правило для проверки. - AllowOverride: В конфигурации Apache (
/etc/apache2/sites-available/000-default.conf
) должно бытьAllowOverride All
для директории сайта. - Порядок правил: Переадресации должны идти перед условиями пропуска, иначе старые URL могут не обработаться.
- Кэш: После изменения
.htaccess
очищайте кэш браузера или проверяйте в режиме инкогнито. - Логи сервера: Если что-то не работает, смотрите
/var/log/apache2/error.log
— там могут быть подсказки.
Вывод
Настройка переадресации оказалась испытанием, но в итоге я разобрался. Главное — понять структуру URL, проверить сервер и правильно организовать правила. Теперь все старые ссылки с vizator.ru
ведут на новые страницы jedig.ru
, и трафик с SEO сохранены. Надеюсь, мой опыт поможет вам избежать моих ошибок!
Код на питоне для формирования ссылок. Но с ошибочкой :)
import pymysql
from dotenv import load_dotenv
import os
# Загружаем переменные окружения из файла .env
load_dotenv()
# Конфигурация подключения к базе K2 (vizator.ru)
k2_db_config = {
'host': os.getenv('VIZATOR_MYSQL_HOST'),
'user': os.getenv('VIZATOR_MYSQL_USER'),
'password': os.getenv('VIZATOR_MYSQL_PASSWORD'),
'db': os.getenv('VIZATOR_MYSQL_DATABASE'),
'charset': 'utf8mb4',
'cursorclass': pymysql.cursors.DictCursor
}
# Конфигурация подключения к базе Joomla (jedig.ru)
jedig_db_config = {
'host': os.getenv('JEDIG_MYSQL_HOST'),
'user': os.getenv('JEDIG_MYSQL_USER'),
'password': os.getenv('JEDIG_MYSQL_PASSWORD'),
'db': os.getenv('JEDIG_MYSQL_DATABASE'),
'charset': 'utf8mb4',
'cursorclass': pymysql.cursors.DictCursor
}
try:
# Устанавливаем подключения к базам данных
k2_conn = pymysql.connect(**k2_db_config)
jedig_conn = pymysql.connect(**jedig_db_config)
with k2_conn.cursor() as k2_cursor, jedig_conn.cursor() as jedig_cursor:
# Шаг 1: Извлекаем данные из K2 с категориями
k2_cursor.execute("""
SELECT i.id AS k2_id, i.alias AS k2_alias, c.alias AS category_alias
FROM viz_k2_items i
LEFT JOIN viz_k2_categories c ON i.catid = c.id
""")
k2_items = k2_cursor.fetchall()
if not k2_items:
print("Не найдено материалов в viz_k2_items. Проверьте базу K2.")
exit(1)
# Шаг 2: Извлекаем данные из Joomla
jedig_cursor.execute("""
SELECT id AS joomla_id, alias
FROM dyutb_content
""")
joomla_items = jedig_cursor.fetchall()
if not joomla_items:
print("Не найдено материалов в dyutb_content. Проверьте базу Joomla.")
exit(1)
# Шаг 3: Создаём словарь соответствий Joomla ID и alias
joomla_alias_map = {item['alias']: item['joomla_id'] for item in joomla_items}
# Шаг 4: Сопоставляем K2 и Joomla по alias
mappings = []
for k2_item in k2_items:
k2_id = k2_item['k2_id']
k2_alias = k2_item['k2_alias']
category_alias = k2_item['category_alias'] or 'uncategorised' # Если категории нет, используем заглушку
joomla_id = joomla_alias_map.get(k2_alias)
if joomla_id:
mappings.append({
'k2_id': k2_id,
'k2_alias': k2_alias,
'category_alias': category_alias,
'joomla_id': joomla_id
})
else:
print(f"Предупреждение: Не найден Joomla ID для K2 материала с alias '{k2_alias}' (K2 ID: {k2_id})")
# Проверяем, есть ли соответствия
if not mappings:
print("Не найдено соответствий между K2 и Joomla. Проверьте алиасы.")
exit(1)
# Шаг 5: Генерируем правила для .htaccess
htaccess_rules = [
"RewriteEngine On",
"RewriteBase /"
]
for mapping in mappings:
k2_id = mapping['k2_id']
joomla_id = mapping['joomla_id']
category_alias = mapping['category_alias']
k2_alias = mapping['k2_alias']
# Правило: <category_alias>/<k2_id>-<k2_alias> → cars/<joomla_id>-<k2_alias>
rule = f"RewriteRule ^{category_alias}/{k2_id}-{k2_alias}$ http://jedig.ru/cars/{joomla_id}-{k2_alias} [R=301,L]"
htaccess_rules.append(rule)
# Добавляем условие для пропуска новых страниц (не начинающихся с известных категорий)
# Пример категорий можно расширить, если их много
known_categories = {m['category_alias'] for m in mappings}
for cat in known_categories:
htaccess_rules.append(f"RewriteCond %{{REQUEST_URI}} !^{cat}/ [NC]")
htaccess_rules.append("RewriteRule ^ - [L]")
# Шаг 6: Записываем правила в файл
with open('redirects.htaccess', 'w') as f:
f.write("\n".join(htaccess_rules))
print(f"Правила переадресации успешно записаны в 'redirects.htaccess'. Всего обработано {len(mappings)} материалов.")
except Exception as e:
print(f"Ошибка: {e}")
finally:
# Закрываем подключения
if 'k2_conn' in locals():
k2_conn.close()
if 'jedig_conn' in locals():
jedig_conn.close()