diff options
author | Florian Merz <me@fiji-flo.de> | 2021-02-11 14:51:05 +0100 |
---|---|---|
committer | Florian Merz <me@fiji-flo.de> | 2021-02-11 14:51:05 +0100 |
commit | c058fa0fb22dc40ef0225b21a97578cddd0aaffa (patch) | |
tree | df20f8b4c724b61cb9c34cdb450a7ac77d690bd0 /files/ru/mozilla/add-ons/webextensions/internationalization | |
parent | 8260a606c143e6b55a467edf017a56bdcd6cba7e (diff) | |
download | translated-content-c058fa0fb22dc40ef0225b21a97578cddd0aaffa.tar.gz translated-content-c058fa0fb22dc40ef0225b21a97578cddd0aaffa.tar.bz2 translated-content-c058fa0fb22dc40ef0225b21a97578cddd0aaffa.zip |
unslug ru: move
Diffstat (limited to 'files/ru/mozilla/add-ons/webextensions/internationalization')
-rw-r--r-- | files/ru/mozilla/add-ons/webextensions/internationalization/index.html | 405 |
1 files changed, 405 insertions, 0 deletions
diff --git a/files/ru/mozilla/add-ons/webextensions/internationalization/index.html b/files/ru/mozilla/add-ons/webextensions/internationalization/index.html new file mode 100644 index 0000000000..36a37820d9 --- /dev/null +++ b/files/ru/mozilla/add-ons/webextensions/internationalization/index.html @@ -0,0 +1,405 @@ +--- +title: Интернационализация +slug: Mozilla/Add-ons/WebExtensions/Интернационализация +translation_of: Mozilla/Add-ons/WebExtensions/Internationalization +--- +<div>{{AddonSidebar}}</div> + +<p>API <a href="/en-US/docs/Mozilla/Add-ons/WebExtensions">WebExtensions</a> предоставляет полезный модуль для интернационализации расширений — <a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/i18n">i18n</a>. В этой статье мы рассмотрим его особенности и пример его работы. Система для расширений, построенных с помощью API WebExtension, i18n похожа на библиотеки JavaScript для i18n, такие как <a href="http://i18njs.com/">i18n.js</a>.</p> + +<div class="note"> +<p>Расширение, используемое в этой статье в качестве примера, — <a href="https://github.com/mdn/webextensions-examples/tree/master/notify-link-clicks-i18n">notify-link-clicks-i18n</a> — доступно на GitHub. Читая последующие секции этой статьи, Вы можете исследовать его исходный код.</p> +</div> + +<h2 id="Структура_интернализированного_расширения">Структура интернализированного расширения</h2> + +<p>Интернационализированное расширение может содержать такие же элементы, как и любое другое расширение — <a href="/en-US/Add-ons/WebExtensions/Anatomy_of_a_WebExtension#Background_scripts">фоновые скрипты</a>, <a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/Content_scripts">встраиваемые скрипты</a>, и т. д. — а также дополнительные инструмены, позволяющие переключаться между разными локализациями. Их можно представить следующим деревом директорий:</p> + +<ul class="directory-tree"> + <li>корневая-директория-расширения/ + <ul> + <li>_locales + <ul> + <li>en + <ul> + <li>messages.json + <ul> + <li>Сообщения на английском (строки)</li> + </ul> + </li> + </ul> + </li> + <li>de + <ul> + <li>messages.json + <ul> + <li>Сообщения на немецком (строки)</li> + </ul> + </li> + </ul> + </li> + <li>и т. д.</li> + </ul> + </li> + <li>manifest.json + <ul> + <li>Метаданные, зависящие от локализации</li> + </ul> + </li> + <li>myJavascript.js + <ul> + <li>Файл JavaScript, получающий локализацию браузера, сообщения, зависящие от локализации, и т. д.</li> + </ul> + </li> + <li>myStyles.css + <ul> + <li>CSS, зависящий от локализации</li> + </ul> + </li> + </ul> + </li> +</ul> + +<p>Давайте отдельно рассмотрим каждый элемент — последующие секции представляют собой шаги, которым стоит следовать во время интернационализации вашего расширения.</p> + +<h2 id="Добавление_локализованных_строк_в__locales">Добавление локализованных строк в _locales</h2> + +<div class="pull-aside"> +<div class="moreinfo">Вы можете определить тэг языка при помощи инструмента <em>Find</em> на <a href="https://r12a.github.io/app-subtags/">странице определения языковых тегов</a>. Обратите внимание на то, что при поиске еужно использовать английское название языка</div> +</div> + +<p>Каждая система i18n требует предоставить строки во всех локализациях, которые Вы хотите поддерживать. В расширениях они хранятся в директории <code>_locales</code>, размещенной внутри корневой директории. Строки каждой локализации (также называемые сообщениями) хранятся в файле <code>messages.json</code>, находящемся в поддиректории <code>_locales</code>, название которой - тег языка локализации.</p> + +<p>Стоит заметить, что если тег включает в себя и базовый язык, и его региональный вариант, то по конвенции эти язык и вариант разделяются дефисом: например, "en-US". Однако в поддиректориях <code>_locales</code>, <strong>вместо дефиса используется нижнее подчеркивание</strong>: "en_US".</p> + +<p>Таким образом, <a href="https://github.com/mdn/webextensions-examples/tree/master/notify-link-clicks-i18n/_locales">в нашем примере</a> существую директории "en" (английский), "de" (немецкий), "nl" (голландский), and "ja" (японский). Внутри каждой из них находится файл <code>messages.json</code> .</p> + +<p>Давайте рассмотрим структуру одного из этих файлов (<a href="https://github.com/mdn/webextensions-examples/blob/master/notify-link-clicks-i18n/_locales/en/messages.json">_locales/en/messages.json</a>):</p> + +<pre class="brush: json notranslate">{ + "extensionName": { + "message": "Notify link clicks i18n", + "description": "Name of the extension." + }, + + "extensionDescription": { + "message": "Shows a notification when the user clicks on links.", + "description": "Description of the extension." + }, + + "notificationTitle": { + "message": "Click notification", + "description": "Title of the click notification." + }, + + "notificationContent": { + "message": "You clicked $URL$.", + "description": "Tells the user which link they clicked.", + "placeholders": { + "url" : { + "content" : "$1", + "example" : "https://developer.mozilla.org" + } + } + } +}</pre> + +<p>Это стандартный файл JSON — каждый из его элементов является объектом с именем, содержащим сообщение (<code>message)</code> и описание (<code>description)</code>. Оба предмета - строки; <code>$URL$</code> — это заполнитель, который заменяется подстрокой, когда элемент <code>notificationContent</code> вызывается расширением. Вы научитесь это делать в секции {{anch("Получение сообщений из JavaScript")}}.</p> + +<div class="note"> +<p><strong>Примечание</strong>: Вы можете найти больше информации о структуре <code>messages.json</code> <a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/i18n/Locale-Specific_Message_reference">здесь</a>.</p> +</div> + +<h2 id="Интернационализация_manifest.json">Интернационализация manifest.json</h2> + +<p>Для интернационализации файла manifest.json нужно предпринять несколько шагов.</p> + +<h3 id="Получение_локализованных_строк_в_манифестах">Получение локализованных строк в манифестах</h3> + +<p>Ваш файл <a href="https://github.com/mdn/webextensions-examples/blob/master/notify-link-clicks-i18n/manifest.json">manifest.json</a> содержит строки, отображаемые пользователю, такие как имя и описание расширения. Если Вы интернационализируете эти строки и поместите их переводы в messages.json, то эти переводы будут отображаться пользователю в зависимости от локализации его браузера.</p> + +<p>Чтобы интернационализировать строки, их нужно указывать следующим образом:</p> + +<pre class="brush: json notranslate">"name": "__MSG_extensionName__", +"description": "__MSG_extensionDescription__",</pre> + +<p>Здесь мы получаем сообщения, зависящие от локализации браузера, а не просто статические строки.</p> + +<p>Чтобы получить строку сообщения, ее нужно указать следующим образом:</p> + +<ol> + <li>Два подчеркивания</li> + <li>Строка "MSG"</li> + <li>Одно подчеркивание</li> + <li>Имя сообщения так как оно указано в <code>messages.json</code></li> + <li>Два подчеркивания</li> +</ol> + +<pre class="notranslate"><strong>__MSG_</strong> + <em>messageName</em> + <strong>__</strong></pre> + +<h3 id="Локализация_по_умолчанию">Локализация по умолчанию</h3> + +<p>Еше одно поле. которое нужно указать в manifest.json — это <a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/default_locale">default_locale</a>:</p> + +<pre class="brush: json notranslate">"default_locale": "en"</pre> + +<p>Этот параметр устанавливает локализацию по умолчанию, используемую, если расширение не поддерживает локализацию браузера пользователя. Любые сообщения, недоступные в текущей локализации, будут браться из той локализации, которая установлена по умолчанию. There are some more details to be aware of in terms of how the browser selects strings — see {{anch("Выбор локализованной строки")}}.</p> + +<h2 id="CSS_зависящий_от_локализации">CSS, зависящий от локализации</h2> + +<p>Локализованные строки также можно получить из CSS-файлов расширения. Например, Вы можете создать поля CSS, зависящие от локализации, так:</p> + +<pre class="brush: css notranslate">header { + background-image: url(../images/__MSG_extensionName__/header.png); +}</pre> + +<p>Этот функционал может быть полезен, однако, возможно, для этих целей стоит использовать {{anch("Заранее определенные сообщения")}}.</p> + +<h2 id="Получение_сообщений_из_JavaScript">Получение сообщений из JavaScript</h2> + +<p>Допустим, Вы добавили сообщения в Ваш manifest.json. Чтобы Ваше расширение начало использовать правильные языки, соответствующие сообщения следует вызывать при помощи JavaScript. <a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/i18n">API i18n</a> достаточно прост и содержит всего 4 основных метода:</p> + +<ul> + <li>Скорее всего, наиболее часто Вы будете использовать {{WebExtAPIRef("i18n.getMessage()")}} — этот сетод используется для получения конкретного сообщения. Примеры его использования можно увидеть ниже.</li> + <li>Методы {{WebExtAPIRef("i18n.getAcceptLanguages()")}} и {{WebExtAPIRef("i18n.getUILanguage()")}} используются, если UI надо менять в зависимости от локализации — например, если Вы хотите, чтобы предпочтения, свойственные носителям какого-либо языка, находились выше в списке, или чтобы формат дат соответствовал локализации браузера.</li> + <li>Метод {{WebExtAPIRef("i18n.detectLanguage()")}} используется для получения языка информации, введенной пользователем, и ее форматирования.</li> +</ul> + +<p>В нашем примере <a href="https://github.com/mdn/webextensions-examples/tree/master/notify-link-clicks-i18n">notify-link-clicks-i18n</a> , <a href="https://github.com/mdn/webextensions-examples/blob/master/notify-link-clicks-i18n/background-script.js">фоновый скрипт</a> содержит следующие строки:</p> + +<pre class="brush: js notranslate">var title = browser.i18n.getMessage("notificationTitle"); +var content = browser.i18n.getMessage("notificationContent", message.url);</pre> + +<p>Первая из них получает поле <code>notificationTitle message</code> из доступного файла <code>messages.json</code>, соответствующее наиболее подходящей локализации . Вторая строка похожа на первую, но в ней метод принимает URL в качестве второго параметра. Зачем? С помощью этого параметра мы указываем, на что нужно заменить заполнитель <code>$URL$</code> в поле <code>notificationContent message</code>:</p> + +<pre class="brush: json notranslate">"notificationContent": { + "message": "You clicked $URL$.", + "description": "Tells the user which link they clicked.", + "placeholders": { + "url" : { + "content" : "$1", + "example" : "https://developer.mozilla.org" + } + } +} +</pre> + +<p>Объект <code>"placeholders"</code> определяет все заполнители и то, откуда их нужно получать. Заполнитель <code>"url"</code> указывает, что информация о нем должна содержаться в $1 — первое значение, заданное внутри второго параметра <code>getMessage()</code>. Поскольку заролнитель называется <code>"url"</code>, <code>$URL$</code> используется для его вызова внутри сообщения (то есть для заполнителя <code>"name"</code> нужно использовать <code>$NAME$</code>, и т. д.). Если Вы хотите задать значения нескольких заполнителей, их можно передавать во второй аргумент {{WebExtAPIRef("i18n.getMessage()")}} в виде массива — массив <code>[a, b, c]</code> передает значения <code>$1</code>, <code>$2</code> и <code>$3</code>, и т. д. внутрь <code>messages.json</code>.</p> + +<p>Давайте посмотрим на пример: изначально сообщение <code>notificationContent</code> в файле <code>en/messages.json</code> такое:</p> + +<pre class="notranslate">You clicked $URL$.</pre> + +<p>Пусть эта ссылка указывает на <code>https://developer.mozilla.org</code>. После вызова {{WebExtAPIRef("i18n.getMessage()")}}, содержание второго параметра становится доступно в messages.json в качестве значения <code>$1</code>, замещающего <code>$URL$</code>, так как это указано в заполнителе <code>"url"</code>. Таким образом, итоговое значение строки:</p> + +<pre class="notranslate">You clicked https://developer.mozilla.org.</pre> + +<h3 id="Прямое_использование_заполнителей">Прямое использование заполнителей</h3> + +<p>Переменные (<code>$1</code>, <code>$2</code>, <code>$3</code>, и т. д.) можно вставлять напрямую в сообщения. Например, можно переписать объект <code>"notificationContent"</code> следующим образом:</p> + +<pre class="brush: json notranslate">"notificationContent": { + "message": "You clicked $1.", + "description": "Tells the user which link they clicked." +}</pre> + +<p>Этот метод может показаться более быстрым и простым, но другой способ (использование <code>"placeholders"</code>) считается лучшей практикой. Это вызвано тем, что имена заполнителей (например <code>"url"</code>) и примеры помогают понять, что означают заполнители — через неделю после написания кода Вы, наверное, забудете, что обозначают заполнители <code>$1</code>–<code>$8</code>, что менее вероятно, если заполнители именованы.</p> + +<h3 id="Заданные_замены">Заданные замены</h3> + +<p>Значения заполнителей можно задавать вручную, если Вы хотите, чтобы каждый раз это значение было одним и тем же, а не определялось переменной в коде. Например:</p> + +<pre class="brush: json notranslate">"mdn_banner": { + "message": "For more information on web technologies, go to $MDN$.", + "description": "Tell the user about MDN", + "placeholders": { + "mdn": { + "content": "https://developer.mozilla.org/" + } + } +}</pre> + +<p>В этом примере мы сами задаем значение заполнителя, а не получаем его из переменной, такой как <code>$1</code>. Это может быть полезно, если сообщение очень сложное, и Вы хотите разделить значения, чтобы сделать строки более читаемыми. К тому же, доступ к этим значениям можно получить внутри программы.</p> + +<p>Вы также можете использовать такие замены для указания частей строки, не нуждающихся в переводе, таких как имена или названия.</p> + +<h2 id="Выбор_локализованной_строки">Выбор локализованной строки</h2> + +<p>Локализации могут быть указаны с помощью кода языка, например <code>fr</code> или <code>en</code>. Они также могут содержать региональный код, например <code>en_US</code> или <code>en_GB</code>, описывающий региональный вариант языка. Когда вы запрашиваете строку у системы i18n, системы возвращает ее используя следующий алгоритм:</p> + +<ol> + <li>Если для текущей локализации существует файл <code>messages.json</code>, содержащий требуемую строку, возвращается она.</li> + <li>Иначе,если текущая локализация — региональный вариант (например <code>en_US</code>) и существует файл <code>messages.json</code> для этого языка, но без указания региона (например <code>en</code>), содержащий строку, возвращается она.</li> + <li>Иначе, если существует файл <code>messages.json</code> для <code>default_locale</code>, указанной в <code>manifest.json</code>, и этот файл содержит нужную строку, возвращается она.</li> + <li>В противном случае возвращается пустая строка.</li> +</ol> + +<p>Рассмотрим следующий пример:</p> + +<ul class="directory-tree"> + <li>корневая-директория-расширения/ + <ul> + <li>_locales + <ul> + <li>en_GB + <ul> + <li>messages.json + <ul> + <li><code>{ "colorLocalised": { "message": "colour", "description": "Color." }, ... }</code></li> + </ul> + </li> + </ul> + en + + <ul> + <li>messages.json + <ul> + <li><code>{ "colorLocalised": { "message": "color", "description": "Color." }, ... }</code></li> + </ul> + </li> + </ul> + </li> + <li>fr + <ul> + <li>messages.json + <ul> + <li><code>{ "colorLocalised": { "message": "<span lang="fr">couleur</span>", "description": "Color." }, ...}</code></li> + </ul> + </li> + </ul> + </li> + </ul> + </li> + </ul> + </li> +</ul> + +<p>Пусть <code>default_locale</code> установлен как <code>fr</code>, а текущая локализация браузера — <code>en_GB</code>:</p> + +<ul> + <li>Вызов <code>getMessage("colorLocalised")</code> вернет "colour".</li> + <li>Если бы в <code>en_GB</code> не было "colorLocalized", то вызов <code>getMessage("colorLocalised")</code>, вернул бы "color", а не "couleur".</li> +</ul> + +<h2 id="Заранее_определенные_сообщения">Заранее определенные сообщения</h2> + +<p>Модуль i18n module предоставляет заранее определенные сообщения, которые можно вызвать таким же образом, как мы это делали в разделе {{anch("Интернационализация manifest.json")}}. Например:</p> + +<pre class="notranslate">__MSG_extensionName__</pre> + +<p>Заранее определенные сообщения используют такой же синтаксис, за исключением <code>@@</code> перед именем сообщения, например:</p> + +<pre class="notranslate">__MSG_@@ui_locale__</pre> + +<p>Следующая таблица содержит различные заранее определенные сообщения:</p> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Message name</th> + <th scope="col">Description</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>@@extension_id</code></td> + <td> + <p>Внутренний UUID расширения. Эту строку можно использовать для создания URL ресурсов внутри расширения.Даже нелокализованные расширения могут использовать это сообщения.</p> + + <p>Это сообщения нельзя использовать в manifest.json.</p> + + <p>Также стоит заметить, что этот ID — <em>не</em> ID аддона, которое возвращает {{WebExtAPIRef("runtime.id")}}, и которое может быть установлено с помощью ключа <a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/applications">applications</a> в manifest.json. Это сгенерированный UUID, содержащийся в URL аддона. Это означает, что данную величину нельзя использовать в качестве параметра <code>extensionId</code> метода {{WebExtAPIRef("runtime.sendMessage()")}}, или для проверки поля <code>id</code> объекта {{WebExtAPIRef("runtime.MessageSender")}}.</p> + </td> + </tr> + <tr> + <td><code>@@ui_locale</code></td> + <td>Текущая локализация; эту строку можно использовать для создания URL, зависящих от локализации.</td> + </tr> + <tr> + <td><code>@@bidi_dir</code></td> + <td>Направления чтения, либо "ltr" для языков, таких как английский, где текст читается слева направо, либо "rtl" для языков, считающихся справа налево, таких как арабский.</td> + </tr> + <tr> + <td><code>@@bidi_reversed_dir</code></td> + <td>Если <code>@@bidi_dir</code> имеет значение "ltr", то возвращает "rtl"; иначе "ltr".</td> + </tr> + <tr> + <td><code>@@bidi_start_edge</code></td> + <td>Если <code>@@bidi_dir</code> имеет значение "ltr", то возвращает "left"; иначе "right".</td> + </tr> + <tr> + <td><code>@@bidi_end_edge</code></td> + <td>Если <code>@@bidi_dir</code> имеет значение "ltr", то возвращает "right"; иначе "left".</td> + </tr> + </tbody> +</table> + +<p>Возвращаясь к нашему примеру, лучше было бы написать:</p> + +<pre class="brush: css notranslate">header { + background-image: url(../images/__MSG_@@ui_locale__/header.png); +}</pre> + +<p>Теперь мы можем хранить изображения в директориях поддерживаемых локализаций — en, de, и т. д. — что выглядит логичней.</p> + +<p>Давайте рассмотрим пример использования сообщений <code>@@bidi_*</code> в файле CSS:</p> + +<pre class="brush: css notranslate">body { + direction: __MSG_@@bidi_dir__; +} + +div#header { + margin-bottom: 1.05em; + overflow: hidden; + padding-bottom: 1.5em; + padding-__MSG_@@bidi_start_edge__: 0; + padding-__MSG_@@bidi_end_edge__: 1.5em; + position: relative; +}</pre> + +<p>Для языков, в которых текст читается слева направо, таких как английский, правила CSS, использующие заранее определенные сообщения, сверху задают такие значения:</p> + +<pre class="brush: css notranslate">direction: ltr; +padding-left: 0; +padding-right: 1.5em; +</pre> + +<p>Для языков, читающихся справа налево, значения будут следующими:</p> + +<pre class="brush: css notranslate">direction: rtl; +padding-right: 0; +padding-left: 1.5em;</pre> + +<h2 id="Тестирование_расширения">Тестирование расширения</h2> + +<p>Начиная с Firefox 45, расширения могут быть временно установлены с диска — подробнее об этом написано в статье <a href="https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Packaging_and_installation#Loading_from_disk">Loading from disk</a>. Сделайте это и попробуйте протестировать наше расширение <a href="https://github.com/mdn/webextensions-examples/tree/master/notify-link-clicks-i18n">notify-link-clicks-i18n</a>. Перейдите на одну из Ваших любимых страниц и нажмите на ссылку, чтобы проверить, появляется ли сообщения, содержащее URL нажатой ссылки.</p> + +<p>Затем измените локализацию Firefox на какую-либо поддерживающуюся расширением, которое Вы хотите протестировать.</p> + +<ol> + <li>Откройте "about:config" в Firefox, и найдите параметр <code>intl.locale.requested</code> (обратите внимание на версию Firefox: в версиях до Firefox 59 этот параметр называется <code>general.useragent.locale</code>).</li> + <li>Если параметр существует, нажмите на него дважды (или нажмите Return/Enter), чтобы выбрать его, введите языковой код локализации, которую Вы хотите протестировать и нажмите "OK" (или Return/Enter). Например, в нашем примере расширение поддерживает "en" (английский), "de" (немецкий), "nl" (голландский), and "ja" (японский). Вы также можете указать пустую строку (<code>""</code>) в качестве значения. В этом случае браузер выберет язык Вашей ОС по умолчанию.</li> + <li>Если параметр <code>intl.locale.requested</code> не существует, нажмите правой кнопкой мыши на список параметров (или откройте контекстное меню при помощи клавиатуры), и выберите "New", а затем "String". Введите <code>intl.locale.requested</code> как имя настройки и, "de", "nl", и т. д. как значение, как это описано в шаге 2.</li> + <li>Найдите <code>intl.locale.matchOS</code> и, если параметр существует и равен <code>true</code>, дважды нажмите на него и установите на <code>false</code>.</li> + <li>Перезапустите браузер, чтобы изменения вступили в силу.</li> +</ol> + +<div class="note"> +<p><strong>Примечание</strong>: Этот метод работает, даже если у Вас не установлен <a href="https://addons.mozilla.org/en-US/firefox/language-tools/">языковой пакет</a> для выбранного языка. В этом случае UI браузера просто будет использовать Ваш язык по умолчанию.</p> +</div> + +<ol> +</ol> + +<div class="note"> +<p><strong>Примечание:</strong> Чтобы изменить результат <code>getUILanguage</code> требуется языковой пакет, поскольку он отражает язык UI браузера, а не язык сообщений расширения.</p> +</div> + +<p>Еше раз загрузите расширение с диска и протестируйте локализацию:</p> + +<ul> + <li>Еще раз откройте "about:addons" — теперь Вы должны увидеть Ваше расширение, его иконку, имя и описание на выбранном языке.</li> + <li>Еще раз протестируйте расширение. Для нашего примера, Вам следовало бы посетить другую страницу и, нажав на ссылку, проверить, появляется ли сообщение на нужном языке.</li> +</ul> + +<p>{{EmbedYouTube("R7--fp5pPGg")}}</p> |