Разработка системы управления переводами (i18n) сайта

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

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

Предлагаемые услуги
Показано 1 из 1 услугВсе 2065 услуг
Разработка системы управления переводами (i18n) сайта
Сложная
от 1 недели до 3 месяцев
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1214
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1161
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    852
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1041
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    823
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    815

Разработка системы управления переводами (i18n) сайта

Система управления переводами — необходима для мультиязычных сайтов, где нужно регулярно добавлять и обновлять тексты на нескольких языках без редактирования кода или JSON-файлов вручную. Переводчики работают в удобном интерфейсе, разработчики добавляют новые ключи через код.

Варианты хранения переводов

Файловый подход (Laravel lang, i18next) — переводы в PHP/JSON-файлах. Минусы: редактирование требует доступа к файловой системе, нет истории изменений, сложно для нетехнических переводчиков.

Database-подход — переводы в БД. Редакторы работают через UI, история изменений, возможность переводить без деплоя. Это рекомендуемый подход для команд с переводчиками.

Гибридный — перевод в файлах как fallback, переопределение через БД.

Модель данных

translation_keys (
  id, key,          -- 'checkout.button.pay', 'nav.home'
  namespace,        -- 'frontend', 'emails', 'admin'
  description,      -- подсказка для переводчика
  created_at
)

translations (
  id, key_id, locale,
  value,            -- переведённый текст
  status: pending | approved | needs_review,
  translated_by, approved_by,
  created_at, updated_at
)

translation_change_log (
  id, translation_id, old_value, new_value, changed_by, changed_at
)

Сбор непереведённых ключей

В коде используются ключи через __() или t(). Artisan-команда сканирует код и добавляет новые ключи в БД:

class ScanTranslationKeys extends Command
{
    public function handle(): void
    {
        $files = File::allFiles(resource_path('views'))
            ->merge(File::allFiles(resource_path('js')));

        $keys = [];
        foreach ($files as $file) {
            $content = File::get($file);
            preg_match_all("/__\('([^']+)'\)/", $content, $matches);
            preg_match_all("/t\('([^']+)'\)/", $content, $jsMatches);
            $keys = array_merge($keys, $matches[1], $jsMatches[1]);
        }

        $unique = array_unique($keys);
        $existing = TranslationKey::pluck('key')->toArray();
        $new = array_diff($unique, $existing);

        foreach ($new as $key) {
            TranslationKey::create(['key' => $key, 'namespace' => $this->guessNamespace($key)]);
        }

        $this->info("Найдено новых ключей: " . count($new));
    }
}

Интерфейс переводчика

Основной экран — таблица с фильтрами:

Фильтры Колонки
Namespace Ключ
Язык Оригинал (ru)
Статус Текущий перевод
Поиск по ключу/тексту Действие: редактировать

Форма редактирования — инлайн в таблице или боковая панель. Рядом с полем перевода — оригинальный текст на базовом языке. Кнопка "Машинный перевод" делает запрос к DeepL или Google Translate API для черновика.

API машинного перевода

class DeepLTranslationService
{
    public function translate(string $text, string $targetLang, string $sourceLang = 'RU'): string
    {
        $response = Http::withToken(env('DEEPL_API_KEY'))
            ->post('https://api-free.deepl.com/v2/translate', [
                'text'        => [$text],
                'target_lang' => strtoupper($targetLang),
                'source_lang' => $sourceLang
            ]);

        return $response->json('translations.0.text');
    }
}

Кеширование переводов

Переводы из БД кешируются в Redis. При изменении — инвалидация только затронутого namespace:

class Translation extends Model
{
    protected static function booted(): void
    {
        static::saved(fn($t) => Cache::forget("translations:{$t->locale}:{$t->key->namespace}"));
    }
}

Экспорт/импорт для переводческих агентств

Для работы с агентствами — экспорт в XLIFF (стандартный формат для CAT-инструментов) или Excel:

// Экспорт непереведённых ключей в Excel
$untranslated = TranslationKey::whereDoesntHave('translations', fn($q) =>
    $q->where('locale', $targetLocale)
)->get();

$export = $untranslated->map(fn($key) => [
    'key'      => $key->key,
    'source'   => $key->translations->where('locale', 'ru')->first()?->value,
    'target'   => ''
]);

return Excel::download(new TranslationsExport($export), 'translations.xlsx');

Процесс добавления нового языка

  1. Добавить locale в config/app.php и запустить php artisan translations:scan
  2. В интерфейсе переводчика выбрать новый язык — показаны все непереведённые ключи
  3. Перевести вручную или через машинный перевод → проверить → утвердить
  4. Включить язык в language switcher сайта

Срок разработки: 4–6 недель для полной системы с интерфейсом переводчиков, машинным переводом, историей изменений и экспортом/импортом.