Улучшить эту документациюМеждународный интерфейс (i18n) и локализация (l10n)
Международный интерфейс (i18n) — это процесс разработки продуктов таким образом, чтобы их можно было легко локализовать для разных языков и культур. Локализация (l10n) — это процесс адаптации приложений и текстов для обеспечения их удобства использования на конкретном культурном или лингвистическом рынке. Для разработчиков приложений международная адаптация приложения означает абстрагирование всех строк и других элементов, специфичных для региональных настроек (например, форматов дат или валют), из приложения. Локализация приложения подразумевает предоставление переводов и локальных форматов для абстрагированных элементов.
Как AngularJS поддерживает i18n/l10n?
AngularJS поддерживает i18n/l10n для фильтров дат, чисел и валют.
Локализуемое множественное число поддерживается через директиву ngPluralize. Кроме того, вы можете использовать расширения MessageFormat, чтобы $interpolate для локализуемого множественного числа и поддержки рода во всех интерполяциях через модуль ngMessageFormat.
Все локализуемые компоненты AngularJS зависят от наборов правил, специфичных для региональных настроек, управляемых сервисом $locale.
Несколько примеров использования фильтров AngularJS с различными наборами правил региональных настроек представлены в каталоге i18n/e2e исходного кода AngularJS.
Что такое идентификатор региональных настроек?
Региональные настройки — это определённая географическая, политическая или культурная область. Наиболее часто используемый идентификатор региональных настроек состоит из двух частей: кода языка и кода страны. Например, en-US, en-AU, и zh-CN — это допустимые идентификаторы региональных настроек, содержащие как коды языка, так и коды стран. Поскольку указание кода страны в идентификаторе региональных настроек необязательно, такие идентификаторы региональных настроек, как en, zh, и sk, также являются допустимыми. Дополнительную информацию об использовании идентификаторов региональных настроек можно найти на сайте ICU.
Поддерживаемые региональные настройки в AngularJS
AngularJS разделяет наборы правил форматов чисел и дат на разные файлы, каждый из которых предназначен для определённых региональных настроек. Список поддерживаемых региональных настроек можно найти здесь.
Предоставление правил региональных настроек AngularJS
Существует два подхода к предоставлению правил региональных настроек AngularJS:
1. Предварительно собранные наборы правил
Вы можете предварительно собрать нужный файл региональных настроек с AngularJS, конкатенировав содержимое файла, специфичного для региональных настроек, в конец файла angular.js или angular.min.js.
Например, в *nix-системах для создания файла angular.js, содержащего правила локализации для немецкой локализации, можно выполнить следующие действия:
cat angular.js i18n/angular-locale_de-de.js > angular_de-de.js
При запуске приложения, содержащего angular_de-de.js скрипт вместо общего скрипта angular.js, AngularJS автоматически настраивается с правилами локализации для немецкой локализации.
2. Включение скрипта региональных настроек в index.html
Вы также можете включить файл js региональных настроек в страницу index.html. Например, если требуется немецкая локализация, вы будете обслуживать index_de-de.html, который будет выглядеть примерно так:
<html ng-app> <head> …. <script src="angular.js"></script> <script src="i18n/angular-locale_de-de.js"></script> …. </head> </html>
Сравнение двух подходов
Оба описанных выше подхода требуют подготовки различных index.html страниц или JavaScript-файлов для каждой региональной настройки, которую может использовать ваше приложение. Вам также необходимо настроить свой сервер для предоставления соответствующего файла, соответствующего требуемой региональной настройке.
Второй подход (включение файла JavaScript региональных настроек в index.html) может быть медленнее, так как необходимо загрузить дополнительный скрипт.
Ограничения
Хотя AngularJS делает i18n удобным, при разработке приложения необходимо учитывать несколько моментов.
Символ валюты
Фильтр валюты AngularJS позволяет использовать символ валюты по умолчанию из сервиса региональных настроек, или вы можете предоставить фильтру пользовательский символ валюты.
Предположим, вы пишете банковское приложение и хотите отобразить баланс счета в 1000 долларов. Вы пишете следующую привязку с использованием фильтра валюты:
{{ 1000 | currency }}
Если ваше приложение в настоящее время находится в en-US региональной настройке, браузер отобразит $1000.00. Если кто-то из японской региональной настройки (ja) просмотрит ваше приложение, их браузер отобразит баланс ¥1000.00 вместо этого. Это проблема, потому что $1000 не равно ¥1000.
В этом случае вам необходимо переопределить символ валюты по умолчанию, предоставив фильтру валюты currency символ валюты в качестве параметра.
Если мы изменим вышеуказанное на {{ 1000 | currency:"USD$"}}, AngularJS всегда будет отображать баланс USD$1000 независимо от региональных настроек.
Длина перевода
Переведённые строки/форматы дат могут значительно отличаться по длине. Например, June 3, 1977 будет переведено на испанский язык как 3 de junio de 1977.
При интернационализации вашего приложения необходимо выполнить тщательное тестирование, чтобы убедиться, что компоненты пользовательского интерфейса ведут себя ожидаемым образом, даже когда их содержимое значительно различается по размеру.
Часовые пояса
Фильтр дат AngularJS использует настройки часового пояса браузера. Одно и то же приложение будет отображать различную информацию о дате в зависимости от настроек часового пояса компьютера, на котором запущено приложение. Ни JavaScript, ни AngularJS в настоящее время не поддерживают отображение даты с часовым поясом, заданным разработчиком.
Расширения MessageFormat
Вы можете писать локализуемые сообщения, основанные на числах и роде, в выражениях интерполяции AngularJS и в вызовах $interpolate.
Это расширение синтаксиса предоставляется модулем ngMessageFormat, от которого может зависеть ваше приложение (отправляется отдельно в виде angular-message-format.min.js и angular-message-format.js). Текущее ограничение модуля ngMessageFormat, заключается в том, что он не поддерживает переопределение начального и конечного символов $interpolate. Разрешены только стандартные символы {{ и }}.
Расширение синтаксиса основано на подмножестве синтаксиса ICU MessageFormat, которое охватывает множественное число и выбор рода. См. ссылки в разделе «Дополнительные материалы» в нижней части этого раздела.
Вам может быть полезно поэкспериментировать со следующим примером во время чтения объяснений ниже:
Синтаксис множественного числа
Синтаксис выбора сообщений на основе множественного числа выглядит следующим образом:
{{NUMERIC_EXPRESSION, plural,
=0 {MESSAGE_WHEN_VALUE_IS_0}
=1 {MESSAGE_WHEN_VALUE_IS_1}
=2 {MESSAGE_WHEN_VALUE_IS_2}
=3 {MESSAGE_WHEN_VALUE_IS_3}
...
zero {MESSAGE_WHEN_PLURAL_CATEGORY_IS_ZERO}
one {MESSAGE_WHEN_PLURAL_CATEGORY_IS_ONE}
two {MESSAGE_WHEN_PLURAL_CATEGORY_IS_TWO}
few {MESSAGE_WHEN_PLURAL_CATEGORY_IS_FEW}
many {MESSAGE_WHEN_PLURAL_CATEGORY_IS_MANY}
other {MESSAGE_WHEN_THERE_IS_NO_MATCH}
}}
Обратите внимание, что пробелы (включая переводы строк) обычно не имеют значения, за исключением случаев, когда они являются частью фактического текста сообщения, который находится в фигурных скобках. Пробелы обычно используются для повышения читабельности.
Здесь NUMERIC_EXPRESSION — это выражение, которое вычисляется до числового значения, в зависимости от которого отображаемое сообщение должно меняться в соответствии с правилами множественного числа.
После выражения AngularJS вы обозначаете синтаксис расширения множественного числа с помощью , plural, элемента синтаксиса. Пробелы здесь необязательны.
За этим следует список ключевых слов выбора и соответствующих пар сообщений. Ключевое слово "other" и соответствующее сообщение обязательны, но вы можете иметь столько других категорий, сколько вам нужно.
Ключевые слова выбора
Ключевые слова выбора могут быть точными совпадениями или зависящими от языка категориями множественного числа.
Точные совпадения записываются как знак равенства, за которым следует точное значение. =0, =1, =2 и =123 — это примеры точных совпадений. Обратите внимание, что пробела между знаком равенства и числовым значением быть не должно.
Совпадения категорий множественного числа — это отдельные слова, соответствующие категориям множественного числа спецификации CLDR. Эти категории различаются в зависимости от региональных настроек. Например, региональные настройки «en» (английский) определяют только «one» и «other», в то время как региональные настройки «ga» (ирландский) определяют «one», «two», «few», «many» и «other». Обычно вы просто записываете категории для своего языка. При переводе переводчики будут добавлять или удалять больше категорий в зависимости от целевой региональной настройки.
Точные совпадения всегда имеют приоритет над совпадениями ключевых слов. Таким образом, если вы определите как =0 и zero, когда значение выражения равно нулю, будет выбрано сообщение =0. (Дублируемые категории ключевых слов полезны при использовании необязательного синтаксиса offset, описанного ниже).
Сообщения
Сообщения сразу следуют за ключевым словом выбора и необязательно предваряются пробелами. Они записываются в одиночных фигурных скобках ({}). Они могут содержать синтаксис интерполяции AngularJS внутри них. Кроме того, символ # — это заполнитель для фактического числового значения выражения.
{{numMessages, plural,
=0 {You have no new messages}
=1 {You have one new message}
other {You have # new messages}
}}
Поскольку эти сообщения могут сами содержать выражения AngularJS, вы можете записать это следующим образом:
{{numMessages, plural,
=0 {You have no new messages}
=1 {You have one new message}
other {You have {{numMessages}} new messages}
}}
Синтаксис множественного числа с необязательным смещением
Синтаксис множественного числа поддерживает необязательный offset синтаксис, который используется в сопоставлении. Проще всего объяснить это на примере.
{{recipients.length, plural, offset:1
=0 {You gave no gifts}
=1 {You gave {{recipients[0].name}} a gift}
one {You gave {{recipients[0].name}} and one other person a gift}
other {You gave {{recipients[0].name}} and # other people a gift}
}}
Когда указано offset, сопоставление выполняется следующим образом. Сначала точное значение выражения AngularJS сопоставляется с точными совпадениями (т. е. =N селекторами) для поиска совпадения. Если совпадение есть, используется это сообщение. Если совпадения не было, то значение смещения вычитается из значения выражения, и к этому новому значению применяются правила локализованного множественного числа, чтобы получить его категорию множественного числа (например, «one», «few», «many» и т. д.), и выполняется попытка сопоставления с селекторами ключевых слов, и используется совпадающее сообщение. Если совпадения не было, используется категория «other» (обязательно). Значение символа # внутри сообщения — это значение исходного выражения, уменьшенное на указанное значение смещения.
Экранирование/цитирование
Вам потребуется экранировать фигурные скобки или символ # внутри текстов сообщений, если вы хотите, чтобы они обрабатывались буквально без специального значения. Вы можете процитировать/экранировать любой символ в тексте сообщения, поставив перед ним символ \ (обратный слэш). Символ обратного слэша удаляет любое специальное значение у символа, который следует за ним. Таким образом, вы можете экранировать или процитировать сам обратный слэш, поставив перед ним ещё один обратный слэш.
Синтаксис пола (иначе select)
Поддержка пола обеспечивается более универсальным синтаксисом «select», который больше похож на оператор switch. Он достаточно универсален для поддержки сообщений, основанных на поле.
Синтаксис выбора сообщения, основанного на поле, выглядит следующим образом:
{{EXPRESSION, select,
male {MESSAGE_WHEN_EXPRESSION_IS_MALE}
female {MESSAGE_WHEN_EXPRESSION_IS_FEMALE}
...
other {MESSAGE_WHEN_THERE_IS_NO_GENDER_MATCH}
}}
Обратите внимание, что пробелы (включая новые строки) обычно не имеют значения, за исключением случаев, когда они являются частью фактического текста сообщения, находящегося в фигурных скобках. Пробелы обычно используются для улучшения читабельности.
Здесь EXPRESSION — это выражение AngularJS, которое вычисляет пол человека, используемого для выбора сообщения, которое должно быть отображено.
Выражение AngularJS следует за , select,, где пробелы необязательны.
За этим следует список ключевых слов выбора и соответствующих пар сообщений. Ключевое слово «other» и соответствующее сообщение являются обязательными, но вы можете иметь столько других значений пола, сколько вам нужно (т. е. это не ограничивается мужским/женским). Однако обратите внимание, что сопоставление регистрозависимое.
Ключевые слова выбора
Ключевые слова выбора — это простые слова, такие как «мужской» и «женский». Ключевое слово «other» и соответствующее сообщение являются обязательными, а другие — необязательными. Оно используется, когда выражение AngularJS не совпадает (не учитывая регистр) ни с одним из указанных ключевых слов.
Сообщения
Сообщения следуют непосредственно за ключевым словом выбора и необязательно предваряются пробелами. Они записаны в одинарных фигурных скобках ({}). Они могут содержать синтаксис интерполяции AngularJS внутри себя.
{{friendGender, select,
male {Invite him}
female {Invite her}
other {Invite them}
}}
Вложение
Как упоминалось в синтаксисе для множественного и выбранного числа, вложенные сообщения могут содержать синтаксис интерполяции AngularJS. Поскольку вы можете использовать расширения MessageFormat в интерполяции AngularJS, это позволяет вкладывать выражения множественного и пола в любом порядке.
Обратите внимание, что если эти сообщения предназначены для переводчика и должны быть переведены, рекомендуется, чтобы сообщения отображались целиком, а не разбивались на части.
Демонстрация вложения
Это взято из примера выше.
{{recipients.length, plural, offset:1
=0 {You ({{sender.name}}) gave no gifts}
=1 { {{ recipients[0].gender, select,
male {You ({{sender.name}}) gave him ({{recipients[0].name}}) a gift.}
female {You ({{sender.name}}) gave her ({{recipients[0].name}}) a gift.}
other {You ({{sender.name}}) gave them ({{recipients[0].name}}) a gift.}
}}
}
one { {{ recipients[0].gender, select,
male {You ({{sender.name}}) gave him ({{recipients[0].name}}) and one other person a gift.}
female {You ({{sender.name}}) gave her ({{recipients[0].name}}) and one other person a gift.}
other {You ({{sender.name}}) gave them ({{recipients[0].name}}) and one other person a gift.}
}}
}
other {You ({{sender.name}}) gave {{recipients.length}} people gifts. }
}}
Отличия от синтаксиса ICU MessageFormat
Этот раздел полезен для вас, если вы уже знакомы с синтаксисом ICU MessageFormat.
Это расширение синтаксиса, основанное на MessageFormat, разработано для обратной совместимости с существующими выражениями интерполяции AngularJS. Главное правило простое: все интерполяции выполняются внутри двойных фигурных скобок. Оператор запятой на верхнем уровне после выражения внутри двойных фигурных скобок приводит к распознаванию расширений MessageFormat. Такой оператор запятой на верхнем уровне в противном случае является недопустимым в выражении AngularJS и используется MessageFormat для указания функции (например, множественного числа/выбора) и её связанного синтаксиса.
Чтобы понять расширение, ознакомьтесь с синтаксисом ICU MessageFormat, как указано в документации ICU. В любом MessageFormat, где у вас есть обычный текст сообщения, и вы хотите заменить выражение, просто поместите его в двойные фигурные скобки вместо одинарных фигурных скобок, которые предписывает MessageFormat. Это имеет огромное преимущество. Вы больше не ограничены простыми идентификаторами для подстановок. Поскольку вы используете двойные фигурные скобки, вы можете вставить туда любые произвольные синтаксические элементы интерполяции, включая вложение других выражений MessageFormat!
Дополнительные материалы
Для получения более подробной информации, пожалуйста, обратитесь к нашему документу проекта. Вы можете узнать больше о синтаксисе ICU MessageFormat на странице Форматирование сообщений | Руководство пользователя ICU.
© 2010–2018 Google, Inc.
Licensed under the Creative Commons Attribution License 4.0.
https://code.angularjs.org/1.6.9/docs/guide/i18n