Почти с самого своего рождения Lingualeo замышлялся как глобальный сервис, с помощью которого студенты по всему миру будут учить английский язык. В качестве полигона для отработки процесса выхода на новые рынки была выбрана Бразилия.

Уже летом 2012 года перед командой встала задача — локализация сервиса Lingualeo на португальский язык. При этом необходимо было создать процесс, легко масштабируемый на другие языки.

Процесс локализации продукта рождался в Черногории, куда команда Lingualeo выезжала для интенсивной работы над новыми фичами. По первоначальной оценке на локализацию должно было потребоваться всего пару недель разработки перед тем, как систему можно будет отдать переводчикам. Оценки оказались чересчур оптимистичными, команда “встряла” на 1,5 месяца. Lingualeo прошла сложный путь и столкнулась с целым рядом проблем, которых другие могут избежать, прочитав этот пост до конца. Мы попросили Игоря Любимова, Head of localization, почетного ветерана локализации Lingualeo, пересказать сюжет в деталях.

Выбор системы

Для того, чтобы выбрать подходящий инструмент, необходимо было определить, какие задачи он будет решать. Прежде всего, нам было важно, чтобы продукт поддерживал локализацию на нескольких платформах: несколько форматов файлов для веб-сайта, Android-приложение, iOS-приложение, Windows Phone-приложение, а так же нас интересовал API — для тесной интеграции CI-системы и платформы для перевода.

Изначально мы рассматривали старый-добрый Pootle, так как наш бэкэнд был написан на PHP, и для локализации использовали gettext с .po-файлами. Быстро поняли, что это не наш вариант, так как для перевода JSON и прочих файлов приходилось писать кучу конвертеров – Pootle не поддерживал весь необходимый нам “зоопарк” форматов. Плюс, не хотелось хостить платформу для переводов у себя, потому начали искать какое-нибудь SaaS-решение.

Наши критерии для выбора: поддержка всех возможных форматов из коробки, возможность добавления новых строк через API, удобный менеджмент прав пользователей, высокий uptime, короткий срок интеграции, а также возможность запустить crowdsource-локализацию в будущем.

В итоге, мы остановились на простом, но функциональном сервисе WebTranslateIt.com (далее – “WTI”), так как он подходил под все наши требования.

Замечу, что если бы мы выбирали систему сейчас, то остановились бы на Crowdin. Она удобнее и интереснее той, которую мы используем, но не настолько, чтобы инвестировать в рефакторинг многих частей проекта.

Итак, WebTranslateIt.com. Это небольшая готовая SaaS-платформа, ее создал француз Эдуард Триер (Edouard Briere). 3-4 года назад она стала настоящей находкой для Lingualeo. На тот момент она нам очень понравилась. У нее было хорошее API и она отвечала основному требованию — возможность локализации различных форматов и платформ. Плюс, дружелюбный создатель очень оперативно отвечал на все вопросы и делал доработки специально для нас.

Кстати, мы написали и опубликовали в Open Source библиотеку под composer (PHP) для работы с WebTranslateIt.com: https://packagist.org/packages/lingualeo/wti-api. Ждём ваших пулл-реквестов!

Процесс интеграции

Веб, расширения для браузеров и мобильная версии
Основная задача, которая стояла перед нами, не нагружать разработчиков лишними задачами по обслуживанию локализации, а сделать все возможное для того, чтобы они были заняты непосредственно созданием продукта. Вопросы локализации должны быть вынесены из основоного workflow. Представляли мы себе это так: разработчик пишет новые строки, отправляет в систему (либо одной командой, либо вообще автоматически), а дальше они переводятся на несколько языков и возвращаются в проект, без каких-либо явных усилий разработчика. Мантра “Что может быть автоматизировано, то должно быть автоматизировано” часто проскакивает в разговорах наших разработчиков.

Наши размышления привели нас к созданию специальной утилиты, которая была призвана облегчить жизнь разработчиков. Для веб-сайта мы написали пару консольных утилит.

Первая добавляет новую строку в выбранный файл.

$ wti-add localizationFilename.json uniqueStringKey
Please provide russian text
> Привет, Хабр!
String is added


Иногда это бывает удобно, но наибольшую пользу приносит вторая утилита, которая парсит наши шаблоны, вытаскивает из них строки для локализации, добавляет их в WTI и делает прочую магию. Чтобы утилита правильно понимала, какие строки стоит переводить, а какие — нет, разработчикам надо просто обрамить соответсвующий текст символом @.

Пример для наших клиентских шаблонов:

<!-- someTemplate.jst до локализации -->
<h1>Привет! Я Лео!</h1>
<!-- someTemplate.jst подготовленный к локализации -->
<h1>@Привет! Я Лео!@</h1>


После этого выполняем:

$ wti-parse someTemplate.jst localizationFilename.json
1 string to add found
Please provide key for “Привет! Я Лео!”
> hi_i_am_leo
1 string parsed and added


И в WTI создается новая строка в файле someTemplate.jst с ключом hi_i_am_leo и русским текстом Привет! Я Лео!, а наш шаблон принимает другой вид:

<!-- someTemplate.jst подготовленный к локализации -->
<h1><%=i18n.localizationFilename.hi_i_am_leo%></h1>


Разработчику остается только закомитить изменения и не париться о переводах.

Подобные парсеры были сделаны и для остальных форматов шаблонов, включая Twig и простые PHP-скрипты с бизнес-логикой. В зависимости от расширения файла, используются разные форматы замены плэйсхолдеров.

В своем процессе работы с git-ветками мы придерживаемся правил git-flow. Это позволяет нам связать CI-систему с задачами из Jira, помогает поддерживать порядок в репозитории, да и вообще, это круто. Раз по номеру тикета у нас опредляется ветка, почему бы её же не использовать и для определения строк для локализации? Вопрос “Какие строки были добавлены в рамках задачи DEV-1940?” снимется сам собой. Мы сделали апгрейд улититы wti-parse – она берет номер текущей ветки и добавляет все строки с дополнительной меткой задачи. В итоге в интерфейсе WTI это выглядит вот так:

image

Строки добавлены, программист идет дальше делать продукт, больше от него по части переводов ничего не требуется.

Далее, при каждой сборке на нашем CI-сервере, из WTI выгружаются последние версии переводов, и это работает, как часы :)

Курсы
В эту же систему мы интегрировали перевод курсов. Курсы – это не интрефейсные строки, их создают контент-менеджеры. Изначально мы пытались делать переводы вручную, через перессылку Word-файлов, но быстро поняли, что это плохая идея: это возможный, но абсолютно не масштабируемый процесс. Вскоре конструктор курсов был интегрирован с WTI. И теперь, как только контент–менеджеры Lingualeo производят какие-либо изменения в курсах (добавляют упражнения, изменяют формулировки и т.д.), они тут же отражаются в WTI. Все переводчики получают уведомления, и запускается выше описанный алгоритм. Таким образом, нам не нужно вручную управлять процессом перевода: всё работает автоматически.

Email-рассылки
Как и любой сервис, выстраивающий тесный диалог со своими пользователями, Lingualeo делает различные email-рассылки. Около 13 000 000 пользователей, десятки миллионов отправляемых писем каждый месяц – в нашем случае не было смысла реализовывать всю инфрастуктуру внутри, поэтому мы используем внешнего email-провайдера. Но вот беда: у нашего провайдера нет встроенных механизмов локализации шаблонов писем, и поэтому мы изобрели очередной “велосипед”, скрестив два API — Emarsys (а именно они рассылают все наши письма) и WTI.
Раз в 6 часов несколько скриптов забирают из Emarsys русские шаблоны писем, выделяют из них строки для локализации, формируют из них файлы для WTI, а из WTI забирают готовые переводы и создают в Emarsys шаблоны на нужных языках. А уже в настройках рассылок используются те или иные шаблоны, в зависимости от родного языка пользователя.

Процесс работы с переводчиками

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

Эта система подходит не только для работы с агентствами по переводу, фри-лансерами или штатными переводчиками, но и для использования крауд-сорсинга в переводе. Когда мы запустили проект “Переведи Lingualeo” и пригласили наших пользователей перевести хотя бы несколько строк на знакомые им языки, мы создали лэндинг и интегрировали страничку со статистикой из WTI с сайтом.

Так выглядит форма для перевода фраз:

image

Интернационализация

В результате, была разработана технологическая платформа и процессы локализации Lingualeo. Это работает и для веба и для мобильных приложений, не требуя постоянного участия членов команды. Локализация прозрачна для разработчиков: они просто пишут код, разрабатывают продукт для целевых рынков. Переводчики делают свою работу независимо от них. Сегодня добавление готовых переводов занимает всего 1-2 дня.

Конечно, перевод продукта – это лишь часть процесса по подготовке продукта к запуску на новых языковых рынках. Локальные валюты, платежные системы, словари для новых языков, создание специальных курсов, заведение групп в социальных сетях на новых языках – все эти активности также максимально упрощены и автоматизированны. Весь процесс настройки сводится к правке нескольких YML-файлов конфигурации, и требуется буквально несколько часов на настройку всего окружения. Но это уже материал для следующей статьи.

Комментарии (9)


  1. Slach
    16.12.2015 14:12
    +1

    Хорошая дельная статья =) Игорь респект


  1. virtualtomato
    16.12.2015 15:37
    +2

    Спасибо Игорю, интересная статья. Всегда думала, что в LinguaLeo не переводят курсы, а создают их с помощью методистов-носителей языка для каждого рынка (пусть и по шаблону). Правильно ли я понимаю, что сейчас у вас курс английского языка для бразильцев написан контент-менеджерами, которые не знают португальского? Почему был выбран подход с переводом, а не созданием контента на нужном языке, и адаптируются ли как-то курсы для разных рынков?


    1. LinguaLeo
      16.12.2015 18:55

      Каждый курс создается командой методистов, лингвистов — носителей языка и контент-менеджеров. Например, лингвист прорабатывает и создает курс совместно с методистом, контент-менеджер вводит этот курс в платформу. Контент — менеджер из Бразилии работает со своей платформой, а контент-менеджер из Турции работает со своей и так далее. Но у нас работают не только лингвисты, контент-менеджеры и методисты, но и переводчики. Не всегда достаточно только создать курс, еще необходимо знать какие-то тонкости в языке. Вот для этого у нас и существует команда переводчиков. В статье не раскрыт весь процесс создания курсов. Есть еще такой аспект, когда курсы создаются только для одной платформы в связи с какими-то культурными особенностями или с особенностями экзаменов.


  1. Viacheslav01
    16.12.2015 16:16

    Статья хорошая, но вот пример из приложения dizzy с верным вариантом ответа чувствовать/ощущать, меня убил :)
    Да и других неоднозначностей материала хватает, но дизи лучший из них :)


  1. scalywhale
    16.12.2015 17:52
    +1

    Игорь, отличная организация процесса — всё понятно и без лишних костылей!
    У меня вопрос такого плана: вписан ли в этот процесс контроль качества локализации и каким образом он осуществляется?
    И как у вас организована работа с терминологией?


    1. LinguaLeo
      16.12.2015 19:26

      Спасибо :)
      При вводе нового языка веб-сайт и все приложения сначала проходят тестирование силами наших QA для поиска явных проблем – слишком длинные строки, непереведённые строки и так далее. После этого передаём тестовые стенды переводчикам, они уже проводят лингвистическое тестирование – исправляют ошибки, связанные с неясным контекстом и меняют формулировки там, где нужно.

      После ввода нового языка переводчики уже не участвуют в регулярном тестировании, все новые фичи QA проверяют в паре разных локалей. Только в паре – потому что проверять все новые фичи во всех локалях слишком затратно, а львиная доля всех проблем будет видна и на одном языке, отличном от русского. Время от времени мы просим переводчиков проверить на продакшене качество локализации и ошибок находится всего-ничего.

      Для терминологии мы используем WTI Term Base. Каждый новый переводчик (а меняются они не часто) проходит «экспресс-тренинг» по сайту и терминам.


      1. scalywhale
        16.12.2015 19:28

        Спасибо за ответ!
        А успех локализации на том или ином рынке замеряете как-нибудь? (ну, кроме количества пользователей и подписок)


        1. LinguaLeo
          16.12.2015 19:34

          Количество пользователей и подписок – это мерило успеха запуска продукта как того, а не только локализации. Какую-то метрику именно для измерения качества перевода не используем, кроме простых отзывов. Например при живом юзаблити-тестировании турецкой версии многие респонденты отмечали высокое качество перевода – приятный язык и лаконичные формулировки. Значит цель достигнута :)


  1. nzim
    18.12.2015 18:24

    Какой у вас сейчас голосовой движок? Год назад произношение слов было не очень, теперь вполне на уровне.