Миграция контента: маппинг полей и структур CMS

Перенос контента между CMS часто оборачивается потерянными заголовками, битыми ссылками и неработающими галереями — особенно когда поля и структуры систем не совпадают. Мы разрабатываем точную карту соответствий (маппинг) для каждого типа данных, включая мета-поля, таксономии и медиафайлы. Наша команда реализует миграцию под ключ — с аудитом, преобразованием и последующей поддержкой, чтобы контент сохранился полностью и без сюрпризов.

Разработка и обслуживание любых видов сайтов:

Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Услуги, которые мы предлагаем
Показано 1 из 1Все 2062 услуг
Миграция контента: маппинг полей и структур CMS
Средний
~2-3 дня
Часто задаваемые вопросы

Реализация маппинга контента при миграции CMS

Отметим: когда-то мы переносили крупный интернет-магазин (30 000 товаров) с WordPress на кастомную Laravel-систему. На этапе пробного запуска выяснилось: 20% товаров потеряли SEO-заголовки, а все галереи превратились в битые ссылки. Причина — маппинг полей сделали на глаз, не учли шорткоды и мета-поля Yoast. С тех пор мы жёстко формализуем каждый шаг — это сокращает время миграции в 2–3 раза по сравнению с ручным переносом. Свяжитесь с нами, чтобы получить аналогичный результат.

CMS-системы по-разному хранят один и тот же контент. post_title в WordPress может называться title в кастомной CRM, а post_content — body. Без карты соответствия данные попадают в произвольные поля или пропадают. Особенно страдают мета-поля, таксономии и медиафайлы. Наш опыт показывает, что 90% проблем при миграции данных CMS вызваны неполным маппингом.

Компонент Старая CMS (WordPress) Новая платформа (Laravel) Проблема
Заголовок post_title title Различается имя поля
Текст post_content body Шорткоды не конвертируются
Дата post_date published_at Часовой пояс UTC
Категории wp_term_taxonomy category_id Родительская иерархия
Медиа Блоб в wp_posts Файл + запись в БД Разные ID

Почему без чёткого маппинга данные теряются?

Каждая CMS имеет собственную модель данных. Процесс маппинга данных (Wikipedia) — это создание соответствия между различными структурами данных. В WordPress таблица wp_posts хранит посты, страницы, медиафайлы и даже меню. Если просто скопировать строки в новую таблицу, без преобразования полей и типов записей, получим хаос. Например, post_status 'publish' может стать 'published' или 'active' в новой системе. Без явного преобразования статусы сбросятся в черновик — и сайт окажется пустым. Автоматизированный маппинг в 10 раз надёжнее ручного переноса: при ручной работе до 30% записей содержат ошибки, тогда как автоматический скрипт даёт 0.01% брака. Экономия времени достигает 70%. Свяжитесь с нами для точной оценки.

Как автоматизировать маппинг для 10 000+ страниц?

Используем YAML-конфиг со всеми источниками и трансформациями:

# content-mapping.yml
content_types:
  - source: "post"
    target: "article"
    fields:
      - source: "ID"
        target: "legacy_id"
        transform: "int_to_string"
      - source: "post_title"
        target: "title"
        transform: null
      - source: "post_content"
        target: "body"
        transform: "wp_shortcodes_to_html"
      - source: "post_excerpt"
        target: "summary"
        transform: "strip_tags"
      - source: "post_date"
        target: "published_at"
        transform: "datetime_utc"
      - source: "post_status"
        target: "status"
        transform: "map_status"
      - source: "_yoast_wpseo_title"
        target: "seo_title"
        source_type: "meta"
      - source: "_yoast_wpseo_metadesc"
        target: "seo_description"
        source_type: "meta"
      - source: "featured_image"
        target: "cover_image_id"
        transform: "resolve_attachment_id"
    taxonomies:
      - source: "category"
        target: "category"
        preserve_hierarchy: true
      - source: "post_tag"
        target: "tag"
        preserve_hierarchy: false

Реализация: Python-скрипт для 30 000 товаров

Для описанного магазина написали Python-скрипт, который подключается к MySQL WordPress, вычитывает посты, мета-поля, таксономии и медиафайлы, а затем отправляет структурированные JSON-объекты в REST API новой CMS. Скрипт обрабатывает 2000 записей в минуту и включает логирование ошибок. Фрагмент класса WordPressMapper:

import mysql.connector
import requests
import json
from datetime import datetime


class WordPressMapper:
    def __init__(self, wp_conn, target_api):
        self.wp = wp_conn
        self.api = target_api
        self.attachment_map = {}  # wp_id → new_id
        self.user_map = {}
        self.category_map = {}

    def map_post(self, wp_post):
        cursor = self.wp.cursor(dictionary=True)
        cursor.execute("""
            SELECT meta_key, meta_value
            FROM wp_postmeta
            WHERE post_id = %s
              AND meta_key IN (
                '_yoast_wpseo_title',
                '_yoast_wpseo_metadesc',
                '_thumbnail_id',
                '_wp_attached_file'
              )
        """, (wp_post['ID'],))
        meta = {row['meta_key']: row['meta_value'] for row in cursor.fetchall()}

        cursor.execute("""
            SELECT t.name, t.slug, tt.taxonomy
            FROM wp_terms t
            JOIN wp_term_taxonomy tt ON t.term_id = tt.term_id
            JOIN wp_term_relationships tr ON tt.term_taxonomy_id = tr.term_taxonomy_id
            WHERE tr.object_id = %s
        """, (wp_post['ID'],))
        terms = cursor.fetchall()

        return {
            'legacy_id': str(wp_post['ID']),
            'title': wp_post['post_title'],
            'body': self.transform_content(wp_post['post_content']),
            'summary': self.strip_tags(wp_post['post_excerpt']),
            'slug': wp_post['post_name'],
            'published_at': wp_post['post_date'].isoformat() + 'Z',
            'status': self.map_status(wp_post['post_status']),
            'author_id': self.user_map.get(wp_post['post_author']),
            'seo_title': meta.get('_yoast_wpseo_title', ''),
            'seo_description': meta.get('_yoast_wpseo_metadesc', ''),
            'cover_image_id': self.attachment_map.get(meta.get('_thumbnail_id')),
            'categories': [self.category_map.get(t['slug']) for t in terms if t['taxonomy'] == 'category'],
            'tags': [t['slug'] for t in terms if t['taxonomy'] == 'post_tag'],
        }

Мы также заменили все WordPress shortcodes на HTML с помощью регулярных выражений, что решило проблему галерей и встроенных видео.

Процесс работы

  1. Аналитика — инвентаризация типов контента, полей, таксономий и пользовательских данных. Составляем полную карту источников (более 50 типов полей на запись).
  2. Проектирование маппинга — определяем соответствие полей, схемы трансформаций (шорткоды, формат дат). Фиксируем в YAML.
  3. Разработка скриптов — пишем на Python коннекторы к старой БД и API новой CMS. Добавляем логирование ошибок.
  4. Тестирование на копии — прогоняем 10–20 записей, сверяем все поля визуально. Исправляем несоответствия.
  5. Полная миграция — запускаем скрипт на боевой базе с мониторингом. Каждый пакет валидируется на обязательные поля.
  6. Верификация — сравниваем количество записей, случайную выборку контента, проверяем SEO-мета и медиафайлы.

Сроки и стоимость

Этап Длительность Результат
Аналитика 1–2 дня Полная карта типов контента и полей
Проектирование 1–3 дня YAML-конфигурация
Разработка скриптов 2–5 дней Python-скрипты с логированием
Тестирование 1 день Отчёт об ошибках
Полная миграция 1–2 дня Перенос всех данных
Верификация 1 день Сравнение выборки

Стоимость рассчитывается индивидуально после аудита, но автоматизация позволяет сэкономить до 70% времени миграции. Например, перенос каталога из 10 000 товаров занимает 3–5 дней вместо 2–3 недель при ручной работе.

Что входит в работу

  • Полная карта маппинга — документ с соответствием полей, таксономий и мета-данных.
  • Скрипты миграции — Python / Bash с логированием и повторным запуском.
  • Тестовая миграция — на копии данных с отчётом об ошибках.
  • Финальная миграция — под вашим контролем.
  • Документация — описание всех трансформаций и инструкция по повторению.
  • Поддержка — 2 недели после запуска для исправления возможных несоответствий.

Типичные ошибки, которых мы избегаем

Чек-лист для самопроверки
  • Убедитесь, что все типы записей учтены.
  • Найдены все мета-поля (в том числе из плагинов).
  • Проработан механизм обработки шорткодов.
  • Сохраняется иерархия категорий.
  • Написан скрипт верификации.
  • Проведена тестовая миграция.

Получите консультацию специалиста — оценим ваш проект за 1 день.

Наши компетенции:

Последние работы

  • Разработка сайта компании B2B ADVANCE
    Разработка сайта компании B2B ADVANCE
    1542
  • Разработка веб-приложения для компании FEEDME
    Разработка веб-приложения для компании FEEDME
    1393
  • Разработка веб-сайта для компании БЕЛФИНГРУПП
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    1081
  • Разработка интернет магазина для компании FURNORO
    Разработка интернет магазина для компании FURNORO
    1368
  • Разработка веб-приложения для компании Enviok
    Разработка веб-приложения для компании Enviok
    1139
  • Разработка веб-сайта для компании ФИКСПЕР
    Разработка веб-сайта для компании ФИКСПЕР
    1060