Улучшить эту документациюМеждународный и локализованный интерфейс (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 позволяет использовать символ валюты по умолчанию из службы локали locale, или вы можете предоставить фильтру пользовательский символ валюты.
Предположим, вы пишете приложение для банка и хотите отобразить баланс счета в 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.7.8/docs/guide/i18n