Привет! Меня зовут Алексей Тимин, инженер группы локализации Badoo. В этом посте я расскажу вам о том, как мы помогаем переводчикам выполнять их сложную работу, и о новом решении с открытым исходным кодом, которое позволяет создавать скриншоты проектов, созданных в Sketch, для различных языков.

Если вы создаете дизайн для многоязычных проектов или работаете в команде, которая разрабатывает проекты такого рода, эта информация будет вам полезна.

В команде локализации Badoo всего два разработчика, но мы остаемся там и создаем очень интересные инструменты:

Память переводов

● Платформа Совместные переводы, доступ к которой можно получить по URL-адресу https://translate.badoo.com/,

● Функциональность для предоставления данному пользователю правильного перевода (в зависимости от языка, пола, предпочтений и даты),

● Система подготовки переводов для A / B тестирования (да, мы проводим тесты для версий перевода, чтобы определить, какая формулировка лучше),

● Десять или около того интерфейсов для работы переводчиков,

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

Перечисленные выше инструменты предназначены для помощи в процессе локализации сайта Badoo и двух мобильных приложений Badoo (для Android и iOS) на 47 языков. Это огромный список дел.

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

Вот как выглядит процесс перевода:

1. Рисуют дизайнеры.

2. Программа программистов.

3. Переводчики переводят.

4. Релиз.

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

В соответствии с тем, что мы думали, процесс мог бы выглядеть следующим образом:

1. Рисуют дизайнеры.

2. Программисты программируют, а переводчики переводят и могут как-то видеть результат своего перевода.

3. Релиз.

Чтобы вам было легче визуализировать проблему, вот несколько диаграмм процесса до и после. Оптимизируемый раздел выделен красным на первой диаграмме:

Наши дизайнеры работают в графическом редакторе Sketch. Мы убедились, что сопутствующая утилита sketch-tool может создавать снимки экрана, а это означает, что при добавлении перевода можно показать переводчику снимок экрана! Однако возник вопрос. Как можно заменить исходные тексты в дизайне, чтобы получить локализованный скриншот?

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

Верно, какова внутренняя структура .sketch-файла?

Представление данных внутри .sketch-файла

В 43-й версии Sketch разработчики начали использовать новый формат .sketch-файла для лучшей интеграции со сторонними сервисами (http://sketchplugins.com/d/87-new-file-format- в скетче-43 ).

Логически дизайн, созданный в Sketch, можно разбить на следующие объекты: страницы, монтажные области и графические элементы. Каждой сущности - странице, монтажной области или графическому элементу - один раз (в момент создания) присваивается уникальный идентификатор (UUID); это не меняется.

Отношения между сущностями можно визуализировать следующим образом:

Посмотрите на изображение ниже, чтобы понять, что есть что в интерфейсе Sketch: iPhone SE и iPhone 7 - две возможные монтажные области, а Page 1 - одна из возможных страниц.

Дизайн, сохраненный в .sketch-файле, представляет собой ZIP-архив, содержащий каталоги с файлами PNG и JSON. Выглядит просто, правда?

Если мы разархивируем .sketch-файл, мы получим дерево каталогов, которое выглядит примерно так:

Информация, относящаяся к каждой странице и связанным объектам монтажной области, сохраняется в pages / *. Json. UUID для объекта страницы служит именем файла; для каждого объекта страницы есть один файл.

Мы легко можем открыть любые страницы / *. Json и отредактировать, например, название одной из монтажных областей. Чтобы определить конкретный файл для редактирования, мы запускаем следующее:

$ grep -l ‘iPhone 7’ pages/*

Смена имени может быть не проблемой, но изменение, скажем, текста «Щелкните здесь» - более сложная задача. Мы прошли через различные форумы и провели различные поиски подходящих библиотек (безуспешно) и поняли, что многие другие люди также ищут решение этой проблемы.

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

Текст на кнопке «Щелкните здесь» упакован в двоичный список, закодированный в строке Base64, которая является значением атрибута сериализованного объекта JS, который находится в одном из файлов, сжатых как ZIP.

Мы не будем касаться вопросов разархивирования и чтения JSON из файлов, но стоит сказать кое-что о формате Property Lists (bplist на схеме выше). Чтобы изменить текст Щелкните здесь, вы можете воспользоваться утилитой plutil. Это позволяет вам ввести новое значение и удалить старое для данного свойства, а также вы можете использовать его для преобразования plist из двоичной формы в XML и наоборот. XML - удобный формат, и для работы с ним доступно множество инструментов. Также возможен экспорт в JSON, однако, во-первых, это означает, что вы теряете типы данных, а, во-вторых, plist не всегда можно преобразовать в JSON. Например, использование plist для экспорта из скетч-файла в JSON не сработало.

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

Выбор подходящей реализации

Вариант 1. Ленивое решение

Мы постарались рассказать переводчикам о JSON, Base64 и bplist, научить их самостоятельно заменять тексты переводами, а затем делать скриншоты. Однако, когда мы показали им консольную команду для предварительного просмотра экспорта:

$ sketchtool export artboards --items='42C53146-F9BF-4EEE-A4F8-BB489F0A3CDA,BF38A95A-F0CD-452E-BE26-E346EBD349CE' --formats=png --save-for-web example_design.sketch

Мы поняли, что этот вариант не сработает (шучу! Мы им ничего не сказали, сразу перешли ко второму варианту☺).

Вариант 2. Лучший способ

Переводчикам не нужно думать о технических проблемах. Все, что им нужно, это сделать снимок экрана при сохранении перевода.

Для этого мы решили разработать сервис, в котором минимальный функционал будет:

1. Определите в .sketch-файле UUID графических элементов, содержащих текст.

2. Создавайте скриншоты с локализованным текстом.

Проект получил название Sketch Modifier и был опубликован на GitHub.

Работа с модификатором эскиза

Чтобы начать использовать модификатор Sketch, вам необходимо установить Sketch и Node.js на macOS. Да, Sketch существует только для macOS. Но если ваш дизайнер работает в Sketch, то у вас должен быть хотя бы один Mac.

Давайте шаг за шагом рассмотрим процесс работы с модификатором эскиза.

Шаг 1. Установка

Найдите компьютер под управлением macOS. Скачайте и установите на него Sketch ​​и Node.js - это легко сделать.

Затем скачайте архив или клонируйте репозиторий с GitHub командой:

$ git clone https://github.com/AlexTimin/sketch-modifier.git

Перейдите в каталог проекта:

$ cd sketch-modifier

Установите зависимости с помощью npm:

$ npm install

И, наконец, запускаем сервер:

$ ./bin/www

Вот и все. Теперь ваш сервер должен ответить, если вы перейдете по URL-адресу http: // localhost: 3000. Вы можете перейти по этому URL-адресу и проверить.

Шаг 2. Загрузите скетч-файл и определите исходные тексты.

В качестве примера возьмем example_design.sketch ​​и загрузим его в систему. Отправьте запрос из каталога, в котором вы сохранили example_design.sketch:

$ curl -F 'data=@example_design.sketch' http://localhost:3000/add-sketch/

.Sketch-файлу будет присвоен UUID. В ответ вы получите JSON следующего вида:

{
  "8a2009c5-36ca-4328-87d6-16aa0c2e2800": { // UUID assigned to example design.sketch. Yours will be different
    "5A0F429A-C974-460A-9482-93AED7456850": { // Page 1
      "C1C29749-B967-494D-8D7E-A484EAB37534": {// iPhone SE
               
        "E335D359-9DF3-4DCC-8B79-E77E38824714": "Click here" // UUID for the text on the button
      }
      ...// information relating to other Artboards
    }
    ... // information relating to other pages
  }
}

Вы можете сохранить эти данные в своей базе данных, отправить их в / dev / null или сделать с ними что-нибудь еще интересное. Но мы сохраняем его в базе данных.

Шаг 3. Создание предварительного просмотра переведенного

Для замены текста необходимо отправить запрос на URL http: // localhost: 3000 / generate-preview /, указав параметры как экранов, так и textReplaces. Список необходимых команд будет приведен ниже, а пока займемся структурой параметров запроса.

В параметре screen мы указываем список UUID артбордов, для которых нужно сгенерировать скриншоты. Значение параметра имеет следующую структуру:

{
    Example Design UUID: [ // example_design.sketch 
        Artboard UUID,  // iPhone SE
        ...
    ]
}

В textReplaces мы указываем UUID текстовых элементов и новый текст для замены. Значение параметра имеет следующую структуру:

{
    Text UUID: “new text, translation”,
    ...
}

Итак, формулируем запрос на создание скриншота. Давайте заменим текст «Нажмите здесь» на «Начни вечеринку!» , Например. Для этого нам понадобится файл generate-preview-request-data, в котором мы указываем значения параметров запроса.

Содержимое файла generate-preview-request-data:

textReplaces={
    "E335D359-9DF3-4DCC-8B79-E77E38824714": "Start the party!"
}&screens={
    "8a2009c5-36ca-4328-87d6-16aa0c2e2800" : [ 
         "C1C29749-B967-494D-8D7E-A484EAB37534"
    ]
}

Выполните команду из каталога, в котором был сохранен файл generate-preview-request-data.

$ curl -X POST -d "@generate-preview-request-data" http://localhost:3000/generate-preview/

Ответ будет структурирован следующим образом:

{
"C1C29749-B967-494D-8D7E-A484EAB37534":“data:image/sSeY+...;base64”,
...
}

Вы, наверное, догадались, что UUID запрошенного снимка экрана является ключом в структуре ответа, а соответствующее значение - это Base64-представление снимка экрана.

Если, скажем, вы сохраните следующий код в example.html (не забудьте заменить src-value)

<img src=”screenshot Base64”>,

а затем откройте example.html в браузере, вы увидите следующий снимок экрана:

Используя модификатор эскиза, вы можете делать снимки экрана до, во время и после локализации, что очень важно. Вы увидите, как ведет себя дизайн при использовании реальных текстов, и поймете, что нужно доработать.

Заключение

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

Исходный код модификатора Sketch доступен на GitHub: https://github.com/AlexTimin/sketch-modifier.

Не стесняйтесь использовать его, предлагайте улучшения и пишите отзывы.