Дванадцять заповідей локалізації



Ви представили новий сайт — і всі в захваті. Ваш дизайн свіжий, код бездоганний, ви повністю готові до запуску. Але тут хтось цікавиться: «А на японському працює?»

Вас кидає в холодний піт: ви поняття не маєте. Сайт працює на англійській, а іншими мовами ви планували зайнятися пізніше. Тепер вам доведеться переписувати весь движок для підтримки інших мов. Дата запуску відкладається, і ви проводите наступні два місяці за виправленням помилок, тільки щоб переконатися, що ви пропустили добру половину з них.

Локалізація робить ваш движок готовим до роботи на будь-якій мові — і буде набагато простіше, якщо ви займетеся нею з самого початку. Компания-локалізатор Alconost переклала для вас дюжину простих правил, завдяки яким можна спокійно працювати в будь-якій точці світу.

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

У більшості файлів ресурсів кожної рядку присвоюється ім'я, що дозволяє вам вказувати для неї різні варіанти перекладу. Багато мови використовують файли конфігурації зразок таких:

name = Username

Або ось такі
.pot
-файли:

msgid "Username"
msgstr "Nom d utilisateur"

Або ось такі XLIFF-файли:

<trans-unit id="1">
source xml:lang="en">Username</source>
<target xml:lang="fr">Nom d utilisateur</target>
</trans-unit>
Потім ці файли довантажує бібліотека, яка використовує комбінацію мови і країни (локаль, щоб визначити правильну рядок.

Після того, як всі рядки будуть винесені в зовнішні файли ресурсів, ви можете відправляти їх перекладачам і отримувати від них переклади окремими файлами для кожної мови, що підтримується вашим додатком.

2. Не допускайте конкатенації рядків
Додавання одного рядка до іншого майже завжди призводить до помилки локалізації. Це добре видно на прикладі такого параметра, як
color
.

Припустимо, у вашому канцелярському магазині є такі товари, як олівці, ручки, аркуші паперу. Покупці будуть вибирати товар і потім його колір. В кошику ви будете показувати їм такі позиції, як «червоний олівець» або «синя ручка» з допомогою функції такого типу:

function getDescription() {
var color = getColor();
var item = getItem();

return color + " " + item;
}

Цей код відмінно працює для англійської мови, в якому колір йде першим — «red pencil», але абсолютно не підходить для французького, на який «червоний олівець» перекладається як «crayon rouge», а «синя ручка» — як «stylo – encre bleue». У французькій мові визначення йдуть після визначаються слів. Функція
getDescription
ніяк не змогла б підтримувати такі мови при простій конкатенації рядків.

Рішення — вказувати параметризрвані рядки, що визначають порядок назви і кольору товару для кожної мови. Визначте рядок ресурсу, яка виглядає таким чином:

itemDescription = {0} {1}

Вона може здаватися незначною, але саме вона робить можливим переклад. Ми можемо ось так використовувати її в новій функції
getDescription
:

function getDescription() {
var color = getColor();
var item = getItem();

return getLocalizedString('itemDescription', color, item);
}

Тепер ваші перекладачі можуть легко змінювати порядок слів, наприклад:

itemDescription = {1} {0}

Так, функція
getLocalizedString
бере ім'я рядка ресурсу (
itemDescription
) і кілька додаткових параметрів (колір і товар), щоб підставити їх значення в рядок ресурсу. Більшість мов програмування містять функцію, аналогічну
getLocalizedString
. (Єдине істотне виключення — JavaScript, але про це ми поговоримо пізніше.)

Цей спосіб також працює для рядків, що містять текст, таких як ця:

invalidUser = The username {0} is already taken. Please choose another one.

3. Внесіть розділові знаки в рядки ресурсів
Доопрацювання пунктуації завжди хочеться залишити на потім, щоб зберегти можливість використовувати одну і ту ж рядок, скажімо, у назві поля, де після неї знадобиться двокрапка, і в підказці, де воно не знадобиться. Але це — ще один поганий приклад конкатенації рядків.

Тут, наприклад, ми додаємо просту форму логіна з використанням PHP в середовищі WordPress:

<form>
<p>Username: <input type="text" name="username"></p>
<p>Password: < input type="text" name="password"></p>
</form>

Нам потрібно, щоб форма працювала і на інших мовах, тому давайте додамо рядка для локалізації. В WordPress це легко робиться за допомогою функції
__
(тобто два нижніх підкреслення поспіль):

<form>
<p><?php echo(__('Username', 'my-plugin')) ?>: <input type="text" name="username"></p>
<p><?php echo(__('Password', 'my-plugin')) ?>: <input type="text" name="password"></p>
</form>

Бачите помилку? Це та сама конкатенація рядків. Двокрапка після тексту не локалізовано. Помилка проявиться в таких мовах, як французький, де двокрапка завжди повинно відбиватися пробілами з обох сторін. Пунктуація — частина рядка і повинна бути включена в файл ресурсів.

<form>
<p><?php echo(__('Username:', 'my-plugin')) ?> <input type="text" name="username"></p>
<p><?php echo(__('Пароль:', 'my-plugin')) ?> <input type="text" name="password"></p>
</form>

Тепер форма може використовувати
Username:
для англійської мови та
Nom d utilisateur :
— для французького.

4. Іноді ім'я — це не ім'я
Мене звати Зак Гроссбарт. Зак — моє ім'я, Гроссбарт — прізвище. У всіх в моїй родині прізвище Гроссбарт, але я — єдиний Зак.

В англомовних країнах першим прийнято називати ім'я, потім прізвище. В більшості азіатських країн — все навпаки, а в деяких культурах користуються одним тільки ім'ям.

Віолончеліст Йо-Йо Ма — представник родини Ма. На китайському він пише першої своє прізвище: Ма Йо-Йо (馬友友).

Але все ще цікавіше, тому що багато людей, переїжджаючи з азіатських країн в англомовні, змінюють порядок згадування імені та прізвища, щоб не порушувати місцеві традиції. Тобто ви не можете робити ніяких припущень.

Ви повинні забезпечити спосіб адаптувати відображення імен; ви не можете припустити, що ім'я завжди буде йти першим або прізвище останньої.

WordPress непогано вирішує цю проблему, запитуючи у вас бажаний варіант відображення вашого імені (Ім'я / Прізвище / Псевдонім / Варіант відображення імені, який видно всім):


Було б навіть краще, якби WordPress підтримував ще й друге ім'я, а також надавав можливість визначити формат для конкретної локалі, щоб ви могли вказати один варіант відображення для англійської мови і інший — для китайського. Втім, досконалості немає межі.

5. Ніколи не прописуйте в коді формат дати, часу або валюти
У світі немає згоди з приводу форматів відображення дати і часу. Хтось пише першим місяць (6/12/2012), а хтось- день (21/6/2012). Одні люди вказують час у 24-годинному форматі (14:00), інші — в 12-годинному (2:00 PM). Тайвань використовує рядка AM і PM у перекладі і ставить їх на початку (上午 2:00).

Ваш найкращий варіант — зберігати всі дати і часу в стандартному форматі, такому як ISO 8601 або UNIX-час, і використовувати бібліотеки зразок Date.js або Moment.js, щоб відображати все для конкретної мови. Ці бібліотеки також справляються з відображенням часу для конкретного часового поясу, так що ви можете зберігати всі дати і час на сервері в загальному форматі (такому, як UTC) і конвертувати в правильний для кожного часового поясу варіант у браузері.

Дати і час не менш складні при відображенні календарів і вибору дат. У США тиждень починається з неділі, у Великобританії — з понеділка, а на Мальдівах — з п'ятниці. Інструмент вибору дат jQuery UI містить більше 50 локалізованих файлів для підтримки різних календарних форматів у всьому світі.

То ж справедливо і для валют та інших числових форматів. В одних країнах в якості роздільника в числах використовують кому, в інших — точку. Завжди використовуйте бібліотеку з локалізованими файлами для кожної локалі, яку вам потрібно підтримувати.

Це питання добре освітлений в обговорення кращих практик відображення літнього часу і часових поясів на StackOverflow.

6. Майже завжди використовуйте UTF-8
Історія комп'ютерних кодувань довжина, але найважливіше — пам'ятати, що 99% часу ваш правильний вибір — це UTF-8. Єдиний випадок, коли UTF-8 не підходить, — коли ви працюєте, в основному, з азіатськими мовами і вам не обійтися без UTF-16.

Це часто трапляється з веб-додатками. Якщо браузер і сервер використовують різні кодування, символи відображаються з спотворенням, і додаток наповнюється квадратами і питальними знаками.

Багато мов програмування зберігають файли в кодуванні, яку система використовує за замовчуванням. Але англомовність вашого сервера не буде мати ніякого значення, якщо всі ваші користувачі переглядають сайт на китайському. UTF-8 вирішує цю проблему, стандартизируя кодування для браузера і сервера.

Задавайте UTF-8 на початку всіх ваших сторінок HTML:

<head>
< meta http-equiv="Content-Type" content="text/html; charset=utf-8">

Вкажіть UTF-8 в заголовку HTTP Content-Type:

Content-Type: text/html; charset=utf-8

Специфікація JSON вимагає, щоб всі документи JSON використовували Unicode, UTF-8 за замовчуванням, так що переконаєтеся, що ви використовуєте UTF-8 при будь-якому читанні або запису даних.

7. Передбачте скорочення і подовження рядків
При перекладі змінюється довжина рядків.


(210 пікселів англійською мовою, 380 — німецькою)

«Повторіть пароль» німецькою — майже вдвічі довший, ніж англійською. Якщо місця недостатньо, ваш рядка наползут на елементи управління. WordPress вирішує цю проблему, залишаючи додаткове місце для кожного рядка на випадок її подовження.


Такий підхід гарний для мов, у яких рядки мають приблизно однакову довжину, але у мовах з довгими словами, — наприклад, німецькою та фінською, — рядки наползут на елементи керування, якщо ви не залишите досить багато місця. Однак якщо ви додасте ще простору, це призведе до того, що в компактних мовах, таких як китайський, назви будуть розташовані дуже далеко від відповідних елементів управління, ускладнюючи користування формою.


Багато дизайнери форм забезпечують достатню додаткове місце для рядків, вирівнюючи їх по правому краю або розміщуючи над елементами управління.


Розміщення тексту над елементами управління вирішує проблему для коротких форм, але довгі — робить занадто довгими.

Ідеального рішення, як забезпечити роботу вашого застосування на всіх мовах, ні; багато дизайнери форм комбінують ці підходи. Короткі підписи на кшталт «Ім'я користувача» або «Роль» незначно зміняться при перекладі і зажадають зовсім трохи додаткового місця. Рядки довші зміняться серйозно і зажадають набагато більше місця в ширину і в висоту.


Тут WordPress залишає трохи додаткового місця для рядка «Біографічна інформація», але розміщує більш довгий опис під полем, щоб забезпечити запас для його збільшення при перекладі.

8. Завжди використовуйте повну локаль
Повна локаль включає в себе мову і код країни, підтримує альтернативні варіанти написання, формати дати і інші особливості, які можуть відрізнятися для двох країн, що використовують одну мову.

Завжди використовуйте при перекладі повну локаль, а не тільки мову, щоб було ясно, що подали на обід — деруни або деруни, і можна було зрозуміти, 100 російських рублів для іншої країни — це багато чи мало.

9. Ніколи не довіряйте браузеру вибір локалі
Локалізація набагато складніше для браузерів і JavaScript, тому що вони визначають локаль в залежності від того, хто запитує.

В JavaScript є властивість, що повідомляє про поточний мовою, яке називається
navigator.userLanguage
. Його підтримують всі браузери, але воно, як правило, марно. Якщо я встановлю Firefox англійською, для
navigator.userLanguage
буде відображатися значення
English
. Тепер я можу зайти в налаштування і змінити вибрані мови. Firefox дозволяє мені вибрати кілька мов, так що я можу встановити в порядку переваги: американський англійський, будь-який інший англійський та японський.


Вибір декількох локалей дозволяє серверам підібрати найкраще відповідність між мовами, які я знаю і вони підтримують. Firefox бере ці локалі і відправляє їх сервера в заголовку HTTP наступним чином:

Accept en-us,en;q=0.7,ja;q=0.3

Firefox навіть використовує якісний фактор (частина з
q=
), для позначення ступеня переваги однієї локалі перед іншою.

Це означає, що сервер може надати контент англійською, японською або іншою мовою, якщо жоден із зазначених він не підтримує. Тим не менш, навіть після встановлення бажаних мов в Firefox, властивості
navigator.userLanguage
, як і раніше, буде прописаний англійська і тільки він. З іншими браузерами ситуація не набагато краща. І закінчитися все може тим, що сервер вирішить, що я віддаю перевагу японський, а JavaScript — що я хочу читати по-англійськи.

JavaScript ніколи не мав вирішення цієї проблеми, і замість єдиної стандартної бібліотеки локалізації в ньому — десятки стандартів. Найкращим виходом із ситуації буде інтеграція в JavaScript-код сторінки локалі, обраної сервером при обробці запиту. Тоді ви можете використовувати локаль при форматуванні будь-яких рядків, дат і чисел з JavaScript.

10. Враховуйте мови з прочитанням зліва направо і справа наліво
Більшість мов пишуться зліва направо, але арабська, іврит і чимало інших пишуться справа наліво. В HTML є властивість для
html
-елемент під назвою
dir
, що визначає, читається сторінка
ltr
(зліва направо) або
rtl
(справа наліво).

<html dir="rtl">

Визначає напрямок властивість є і в CSS:

input {
direction: rtl;
}

Після установки властивості
direction
сторінка буде працювати по стандартної HTML-розмітки, але CSS-властивості
float:
не переключаться з
left
на
right
, і абсолютне позиціонування залишиться незмінним. Для більш складних макетів знадобиться нова таблиця стилів.

Простий спосіб визначити напрямок поточного мови — включити рядок
direction
в винесені ресурси рядка.

direction = rtl

Тепер ви можете використовувати цю рядок для завантаження іншої таблиці стилів, прив'язаною до поточної локалі.

11. Ніколи не сортуйте в браузері
JavaScript містить функцію
sort
, яка сортує рядка в алфавітному порядку. Вона робить це, порівнюючи кожен символ в кожному рядку, щоб визначити, чи більше a, ніж b, і менше y, ніж z. Тому вона поставить 40 перед 5.

Браузер визначає, що y йде перед z, використовуючи велику таблицю відповідностей для кожного символу. Втім, браузер включає ці таблиці лише для поточної локалі. Це означає, що браузер не зможе правильно відсортувати список японських назв засобами англійської мови; він відсортує їх за значенням Unicode, що невірно.

Цю проблему можна спостерігати в таких мовах, як польський і в'єтнамська, в яких часто використовуються діакритичні знаки. Браузер може визначити, що a йде перед b, але не знає, чи йде перед ã.

Правильно сортувати може тільки сервер. Переконайтеся, що сервер має в своєму розпорядженні усіма картами коду для підтримуваних мов, що ви відправляєте браузеру відсортовані списки і що ви звертаєтеся до сервера всякий раз, коли хочете їх пересортировать. Переконайтеся також, що при сортуванні сервер приймає до уваги локаль (включаючи всі з прочитанням справа наліво).

12. Тестуйте раніше і частіше
Більшість команд не турбується про локалізації до тих пір, поки не стане занадто пізно. Великий клієнт в Азії поскаржиться, що сайт не працює, — і всі кинуться виправляти 100 дрібних помилок локалізації, про яких ніхто й не думав. Якщо слідувати наведеним у цій статті правил, можна уникнути багатьох проблем з локалізацією, але тестувати все одно доведеться, а переклади, як правило, не будуть готові до кінця проекту.

Раніше я перекладав свої проекти на поросячью латинь, але так не перевірялися азіатські символи, і її не підтримує більшість браузерів. Зараз я тестую переклади з допомогою мови коса (
xh_ZA
). Всі браузери підтримують коса, а для Нельсона Мандели — це рідна мова, але мене ніхто ніколи не просив підтримувати його продукту.

Я не говорю коса, тому створюю новий файл перекладу і додаю
xh
в початок і кінець кожного рядка. Так легко помітити, чи не пропустив я рядок в коді. Вставляю ще кілька ієрогліфів японського кандзі для перевірки кодування і отримую безладну рядок, за допомогою якої можна перевірити всі нюанси моїх перекладів.

Створити файл для тестового перекладу легко. Просто збережіть кілька файлів конфігурацій з
xh_ZA
в імені файлу і замініть…

name = Username

… на:

name = xh吳清源Username吳清源xh

Отримана суміш дозволяє перевірити, переніс я всі рядки ресурси, використовую чи правильну локаль, підходять мої форми для більш довгих рядків і правильну кодування я використовую. Потім я швидко сканую додаток на все, де немає
xh
, і виправляю помилки до того, як вони стануть нагальними проблемами.

Підійдіть до локалізації правильно заздалегідь — і ви вбережете себе від великих проблем у перспективі. А ми в Alconost готові вам допомогти — від безкоштовної консультації до власне локалізації.
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.