Как я упоминал во введении к этой лекции, примерно 60% пользователей используют, в некотором объеме, функции специальных возможностей. Иногда – это потому что эти люди имеют реальные физические ограничения, иногда – лишь потому, что им это нравится, и иногда – лишь для того, чтобы облегчить использование устройства в определенных условиях.
Во многих странах доступность применения чего-либо людьми с ограниченными физическими способностями (в нашем случае речь идет о специальных возможностях программного обеспечения) – это требование законодательства, в итоге, это необходимо, если вы планируете сделать приложение доступным для подобных регионов. Коротко говоря, поддержка специальных возможностей – это то, что вашему приложению следует реализовать, и оно должно делать это хорошо. К счастью, это не такая уж и сложная задача, как может показаться. (Посмотрите материалы "Создание специального приложения" (http://msdn.microsoft.com/library/windows/apps/hh452681.aspx) и "Введение в использование специальных возможностей в Веб" (http://msdn.microsoft.com/library/windows/desktop/gg671915.aspx). Второй материал посвящен веб-приложениям, но вполне применим и для приложений для Магазина Windows . Кроме того, посмотрите материалы "Руководство и контрольный список для специальных возможностей" (http://msdn.microsoft.com/library/windows/apps/hh700325.aspx), "Методики, которых следует избегать при создании приложений со специальными возможностями" (http://msdn.microsoft.com/ru-ru/library/windows/apps/hh452715.aspx) и "Реализация специальных возможностей для определенных типов содержимого" (http://msdn.microsoft.com/library/windows/apps/hh700326.aspx)).
Может показаться, для реализации специальных возможностей понадобится много работы, так как разработчики сравнительно мало знакомы с тем, что это означает. Чтобы это исправить, потратьте несколько минут на то, чтобы получить непосредственный опыт работы со специальными возможностями. Но, прежде чем вы сделаете что-то еще:
Пройдите в раздел Параметры ПК>Синхронизация параметров (PC Settings>Sync Your Settings) и выключите опции Персонализация рабочего стола (Desktop Personalization) и Специальные возможности (Ease of Access). В противном случае, эффекты, с которыми вы экспериментируете будут перемещены на другие устройства, которые могут у вас быть. Я узнал это на собственном опыте, когда я экспериментировал с настройками контрастности на ноутбуке, после чего экран игры, в которую хотел поиграть мой сын на планшете, практически полностью почернел! Очевидно, то приложение не поддерживало схему высокой контрастности, но мне понадобилось некоторое время для того, чтобы во всём разобраться!
Теперь, когда мы позаботились об этих деталях, попробуйте следующее:
Благодаря полученному опыту, я надеюсь, вы получили некоторое понимание того, что означают специальные возможности. Проще говоря, они предназначены для ключевых сценариев поддержки доступности приложений: это работа с экранным диктором, ввод данных только с помощью мыши или только с помощью клавиатуры, схемы с высокой контрастностью и масштабирование разрешения.
Две последних темы раскрыты в Главе 6 курса "Введение в разработку приложений для Windows 8 с использованием HTML, CSS и JavaScript", там рассказано, как работать с различными масштабами разрешения, как обрабатывать различные размеры экрана (что может произойти в результате масштабирования разрешения) и как предоставлять растровые изображения для различных масштабов разрешения для обеспечения их наилучшего вида. В качестве краткого руководства вы так же можете воспользоваться примером "Масштабирование в соответствии с DPI" (http://code.msdn.microsoft.com/windowsapps/Scaling-sample-cf072f4f).
Особенности ввода так же обсуждались в Главе 3 курса "Пользовательский интерфейс приложений для Windows 8, созданных с использованием HTML, CSS и JavaScript". Напоминаю вам снова, что политика сертификации приложения (раздел 3.5.) требует, чтобы приложения поддерживали все формы ввода. Обычно это не проблема в случае с мышью и сенсорным экраном. Настоящая работа начинается тогда, когда нужно убедиться в том, что вашим приложением можно пользоваться, применяя лишь клавиатуру. Обратитесь за подробностями к материалу "Реализация специальных возможностей клавиатуры" (http://msdn.microsoft.com/library/windows/apps/hh700327.aspx). Тестирование приложения с использованием Экранного диктора так же позволяет обнаружить, уделили ли вы достаточно внимания навигации с помощью клавиатуры, так как неважно, какие подписаны ваши элементы управления, если пользователь даже не может установить на них фокус ввода!
Так же полезно упомянуть, что включение скрытых подписей в видео может помочь людям с ослабленным слухом. Выполнение этого, однако, больше относится к видеоданным, или может быть реализовано с помощью наложения текстового элемента на элемент управления, выводящий видео. Смотрите материал "HTML5 и специальные возможности" (http://msdn.microsoft.com/en-us/magazine/hh204741.aspx) в MSDN Magazine для того, чтобы больше узнать о специальных возможностях видео.
Посмотрим теперь, как мы можем поддержать возможности работы с Экранным диктором и высококонтрастные схемы.
Windows SDK включает в себя два инструмента, которые могут помочь вам проверить вашу реализацию специальных возможностей. Первое называется Inspect, это средство для автоматической проверки пользовательского интерфейса, которое проверяет данные специальных возможностей, которые вы предоставляете экранному диктору и даёт вам знать, что вы пропустили. Второе называется AccChecker, которое выполняет серию проверок всего приложения. Вы можете найти эти инструменты в папке установки Windows SDK, обычно в c:\Program Files (x86)\Windows Kits\8.0\bin\x86. Кроме того, вас могут заинтересовать инструменты Accessible Event Watcher и UI Automation Verify. Подробности об их использовании можно найти в материалах "Инструменты тестирования" (http://msdn.microsoft.com/library/windows/desktop/dd373661.aspx) и "Проверка специальных возможностей приложения" (http://msdn.microsoft.com/library/windows/apps/hh452726.aspx). Конечно, для наиболее полного тестирования, найдите несколько пользователей, которые регулярно работают с технологиями специальных возможностей, настройте им лицензию разработчика (так вы сможете установить у них пакет приложения) и передайте им приложение для тестирования.
Подготавливая ваше приложение к возможности навигации с помощью клавиатуры, не используйте атрибуты tabindex для элементов, которые в них не нуждаются, полагая, что подобный поможет Экранному диктору работать с неинтерактивными элементами. Это, на самом деле, не так. Экранный диктор имеет собственные клавиатурные команды (CapsLock+клавиши-стрелки) и собственные режимы навигации, которые позволяют ему прочесть для пользователя всё, что находится на экране, независимо от tabindex. По этим причинам, установка атрибута tabindex для статических элементов вредит удобности работы с Экранным диктором. Вам следует устанавливать это свойство только для интерактивных элементов. Другими словами, нужно понимать, что работа с приложением с использованием клавиатуры и работа с Экранным диктором – это разные вещи, и размышляйте о tabindex только в контексте навигации с помощью клавиатуры.
Средства для чтения с экрана, наподобие встроенного Экранного диктора, могут работать только тогда, когда приложения предоставляют некоторые данные, которые сообщают средству чтения с экрана об элементах управления в пользовательском интерфейсе. В случае с приложениями для Магазина Windows , написанных на HTML, CSS и JavaScript, это реализуется с помощью атрибутов aria-* элементов пользовательского интерфейса.
Совет. Если вам нужны отдельные возможности по переводу текста в речь, то, например, API Microsoft Translator (http://www.microsofttranslator.com/dev/), включает в себя метод Speak, доступный посредством интерфейсов AJAX, SOAP, и HTTP, генерирующее WAV или MP3-поток для текста на заданном языке. Существуют и другие веб-сервисы для этой цели, и библиотеки сторонних разработчиков.
ARIA – это сокращение для Accessible Rich Internet Applications, стандарта, который выражен в спецификациях WAI-ARIA (http://www.w3.org/TR/wai-aria/). WIA расшифровывается как W3C Web Accessibility Initiative (http://www.w3.org/WAI/intro/aria.php). Два других W3C-документу, связанные с этой темой, это WAI-ARIA Primer (http://www.w3.org/TR/wai-aria-primer/) и WAI-ARIA Authoring Practices (http://www.w3.org/TR/wai-aria-practices/).
Это сводится к тому, что вспомогательные технологи, наподобие Экранного диктора, могут автоматически получать из определенных элементов то, что им нужно, наподобие заголовков, абзацев, атрибута title, элементов label, связанных с элементом, который может принимать фокус ввода (с использованием атрибута надписи for), текста кнопок, элементов ввода данных, атрибута таблиц caption, и атрибута alt элементов img. Атрибуты играют здесь немалую роль.
Для всего остального, такого, как элементы ) в Центре разработчиков Windows. Еще один хороший материал, это "Предоставление основных сведений об элементах пользовательского интерфейса" (http://msdn.microsoft.com/library/windows/apps/Hh700323.aspx), который содержит примеры использования основных атрибутов aria-*. На данной странице есть особое замечание по поводу элемента canvas. Так как этот элемент, по сути, представляет собой набор пикселей, он обычно не имеет содержмого, доступного средствам чтения с экрана, даже если выводимые им данные выглядят как текст. Таким образом, нужно приложить особые усилия для того, чтобы придать этому элементу соответствующие атрибуты, как делается с другими пользовательскими элементами управления (сновап посмотрите материал "HTML5 и специальные возможности" (http://msdn.microsoft.com/en-us/magazine/hh204741.aspx), в частности, раздел, посвященный canvas).
Все элементы управления WinJS полностью снабжены атрибутами ARIA, они так же работают с технологиями специальных возможносей, поэтому используя их, вы получаете реализацию этих возможностей по умолчанию (Исключение – это элемент управления SematicZoom, который обычно не имеет атрибута aria-label, так как является контейнером для других элементов управления, которые должны иметь собственные подписи). Таким образом, вам всё еще нужно соовтетствующим образом поработать с другими элементами, в том числе и HTML-элементами управления наподобие progress. Вот сводка по основным атрибутам aria- *:
aria-label Напрямую предоставляет текст для средств чтения с экрана.
aria-labelledby (Обратите внимание на две буквы l) Задает идентификатор другого элемента, который содержит подпись для элемента. Спецификация сообщает, что атрибут aria-labelledby следует использовать вместо aria-label, если необходимый текст уже выведен на экран.
aria-describedby Похож на aria-labelledby, идентифицирует элемент, который содержит более полное описание, а не только текст подписи. Экранный диктор читает этот текст, если пользователь нажимает комбинацию клавиш Win+Alt+F для элемента, имеющего этот атрибут. Это хороший атрибут для использования с элементом canvas, который содержит текст, выведенный в виде графики: если вы так же сохраните этот текст в другом элементе, связанном с данным атрибутом, даже в скрытом, у пользователя будет возможность услышать прочитанное экранным диктором содержимое этого элемента.
aria-valuemin, aria-valuemax, и aria-valuenow У элементов div, роль которых в предоставлении доступа к полосам прокрутки, индикаторам выполнения задач, кнопкам-счетчикам, эти атрибуты показывают значения внутри элемента управления. aria-valuetext так же может предоставлять текст, который связан со значением aria-valuenow.
aria-selected, aria-checked, aria-disabled и aria-hidden Указывают на состояние элемента.
aria-live Нужен для содержимого, которое динамически изменяется, такого, как список основных сведений, чат, RSS-канал, загрузка фрагментов и так далее.
В Главе 4 курса "Введение в разработку приложений для Windows 8 с использованием HTML, CSS и JavaScript" мы рассматривали специальный синтаксис, который применяется для привязки данных к атрибутам целевых элементов, которые не связаны с JavaScript-свойствами. Атрибуты aria-* представляют собой примеры подобных атрибутов, со своими именами, которые пишутся через дефис, для работы с которыми мы используем this[ ] а так же специальные WinJS-инициализаторы в data-win-bind:
<div data-win-bind="this['aria-label']: title WinJS.Binding.setAttribute"></div> <div data-win-bind="this['aria-label']: title WinJS.Binding.setAttributeOneTime"></div>
Более вероятно, однако, что вы будете предоставлять локализованные ARIA-подписи в ресурсах приложения, и для них используется другой декларативный синтаксис, который мы увидим позже, в разделе "Готовность к мировому рынку и локализация".
Для того чтобы увидеть, как Экранный диктор работает с различными атрибутами aria-* лучше всего обратиться к уникальному примеру работы с ARIA (http://code.msdn.microsoft.com/windowsapps/Aria-sample-f3cf5323) в Windows SDK. Одна из его уникальных характеристик заключается в том, что он не выглядит как пример SDK, как вы можете видеть на рис 16.1. Это сделано преднамеренно, для показа содержимого типичного приложения, без использования обычных элементов оформления, используемых в примерах. В данном случае пример имитирует простое чат-приложение с чем-то вроде списка основных сведений в левой части окна.
(рис 16.1) Главное окно примера работы с ARIA
Когда вы запустите этот пример, на забудьте включить Экранный диктор для того, чтобы слышать то, что он говорит. (Рекомендую делать это в имитаторе Visual Studio, так как в таком случае Экранный диктор будет работать лишь в данном сеансе работы, а не для всего вашего компьютера!). Вы обнаружите, что он точно отражает то, что происходит на экране, в особенности то, как вы переходите между элементами управления с помощью Tab или Shift+Tab, нажимаете клавиши Enter или Пробел для выбора элементов и вводите текст в чат. Опять же, выключите монитор, закройте глаза, притворитесь незрячим или предложите своему пятилетнему ребенку стать позади вас и закрыть вам глаза ладошками для того, чтобы получить полные ощущения от работы с примером.
Нажатие Enter на элементе в списке, который расположен слева, обновляет контактные данные, которые находятся в нём. Выбор одного из этих контактов и нажатие Enter откроет другую страницу с таблицей, очевидно, не содержащую реальных данных, но она демонстрирует применение атрибутов aria-*. Страница, показанная на рис 16.2, так же предоставляет возможность испытать навигацию посредством клавиатуры и Экранного диктора.
(рис 16.2) Дополнительная страница примера работы с ARIA (слегка обрезано)
За исключением небольшого кода в pages/chat/chat.js, предназначенного для работы с окном чата, по-настоящему интересная часть этого примера целиком содержтся в разметке, в частности, в файлах pages/chat/chat.html (главная страница) и pages/table/ table.html (дополнительная страница). В коде первой мы видим aria-label у большинства из элементов управления (с текстом, который вы можете слышать, перемещаясь по странице), и гораздо больший набор атрибутов для элемента div, который выводит окно чата около нижней части:
<div class="chatpage fragment">
<header aria-label="Header content" role="banner">
<button class="win-backbutton" aria-label="Back" disabled=""></button>
<h1 class="titlearea win-type-ellipsis">
<span class="pagetitle">Aria Sample</span>
</h1>
</header>
<section aria-label="Main content" role="main">
<div class="chat">
<div class="groupslist" aria-label="List of groups" data-win-control="WinJS.UI.ListView"
data-win-options="{ selectionMode: 'none'}"></div>
<div class="contactslist" aria-label="List of contacts" data-win-control="WinJS.UI.ListView"
data-win-options="{ selectionMode: 'none' }"></div>
<div class="chatTextContainer">
<div class="chatTextEchoContainer" aria-label="Chat text area"
aria-live="assertive" aria-multiline="true" aria-readonly="true" aria-relevant="additions" role="log"
tabindex="0"></div>
<input class="chatTextInput" accesskey="i" aria-label="Chat input area" type="text"
value="Type here..."/>
</div>
</div>
</section>
</div>
Этот div, с классом chatTextEchoContainer, обновляется во время выполнения программы и включает в себя при этом дочерние div-элементы для каждой текстовой записи. По этой причине у него есть атрибут aria-live, значения которого описываются как "уровень вежливости" в спецификациях W3C. Значение assertive сообщает "применить изменения сразу же", что подходит для чата, но этим следует пользоваться осторожно. Другое значение, polite (значение по умолчанию для элементов role="log"), указывает на более низкий приоритет, то есть Экранный диктор не будет прерывать текущую задачу по озвучиванию. Атрибут aria-relevant="additions" относится к этому, показывая, какие изменения относятся к динамически изменяющейся (live) области. Его возможные значения: additions, removals, text, и all. В случае со значением additions, если мы добавим в окно чата изображение для него с атрибутом alt, оно будет озвучено. Если же мы установим его в значение text, озвучиваться будет лишь содержимое текстовых элементов.
Атрибут aria-multiline указывает на то, что окно чата – это многострочный текстовой элемент, то есть, нажатие на клавишу Enter воспринимается как ввод текстового символа перевода строки, а не как команда для отправки сообщения (как в случае однострочного текстового элемента). Атрибут aria-readonly показывает, что содержимое элемента управления нельзя править для того, чтобы отличать такие элементы от тех, которые маркированы атрибутом aria-disabled.
Если вы поэкспериментируете с примером, вы заметите, что когда вы активируете окно чата, Экранный диктор читает всё его содержимое. Когда вы вводите строку в однострочный элемент управления, с другой стороны, Экранный диктор читает лишь те символы, которые были добавлены. Это происходит потому, что для атрибута aria-atomic (он не представлен в разметке) значение по умолчанию – false. При использовании с элементом, маркированным как aria-live это сообщает средству чтения с экрана, что нужно читать только изменившийся узел в данном элементе. Если вы установите aria-atomic в true, изменения любого дочернего элемента будут считаться элементами всего элемента, в итоге, всё его содержимое будет прочитано. Это можно использовать на разных уровнях, заметьте, таким образом, если вы добавляете дочерний элемент, который является атомарный, а потом добавляете внучатый элемент в него, лишь содержимое этого атомарного дочернего элемента будет прочитано, если родительский элемент не является атомарным.
Что касается разметки на странице pages/table/table.html, она дает нам пример использования aria-describedby. Вот соответствующий раздел этой разметки, содержимое таблицы опущено:
<div class="detail">
<h2 id="title" role="heading" aria-level="2">Sample table</h2>
<p id="subtitle" role="note">This table shows sample data.</p>
<p class="generaltext">...</p>
<table class="tabledetail" aria-describedby="subtitle"
aria-labelledby="title" border="1">
<!-- Содержимое опущено -->
</table>
</div>
Когда вы устанавливаете на таблицу фокус ввода в исполняющемся примере (вы должны использовать для этого мышь, если только вы не добавили tabindex к таблице), вы сначала услышите "Sample table" в соответствии с атрибутом aria-labelledby. Затем нажмите Win+Alt+F, и вы услышите текст "Item described by…", за которым будет следовать текст, заданный aria-describedby.
Отметим, наконец, что очень важно, чтобы элементы title и subtitle так же имели атрибуты, имеющие отношение к aria-, такие, как role. В противном случае aria-labelledby и aria-describedby работать не будут.
Работа с моделями высокой контрастности, это, преимущественно, принятие изменения цветовой темы Windows и проверка того, что графические элементы вашего приложения соответствуют требованиям высокой контрастности. С технической точки зрения, высокая контрастность, как её определяет W3C это минимальный коэффициент контрастности 4.5:1. Полное пояснение того, как измерить этот коэффициент, расположено по адресу (http://www.w3.org/TR/WCAG20-TECHS/G18.html). Анализатор контрастности (http://www.paciellogroup.com/node/18?q=node/20) от Paciello Group так же позволяет проверить изображения (некоторые из моих в приложении "Here My Am!" тест не прошли). Обратите внимание, однако, что создание высококонтрастной графики не требуется для содержимого, не несущего информацию, такого, как логотипы и декоративные изображения. В то же время, полноцветная графика может выглядеть не на своём месте в высококонтрастном режиме, поэтому не забудьте оценить общее впечатление от программы при работе с ней пользователей в подобных условиях.
Приложение может поддерживать высокую контрастность с помощью четырех подходов. Первый заключается в том, чтобы использовать встроеные элементы управления (и HTML и WinJS) и позволить системе делать свою работу! Для того, чтобы увидеть, что произойдёт, запустите несколько примеров использования элементов управления, например "Основные элементы управления HTML" (http://code.msdn.microsoft.com/windowsapps/Common-HTML-controls-and-09a72a24) и "HTML-Элемент управления Rating" (http://code.msdn.microsoft.com/windowsapps/Rating-control-sample-4666c750) и пеереключайтесь между разными темами высокой контрастности в разделе Персонализации Панели управления..
Конечно, почти всегда у приложения есть некоторые собственные элементы управления, такие, как div-элементы с пользовательскими цветовыми схемами, заданными в CSS. Вам следует убедиться, есть ли у вас подходящие правила стилей для настроек высокой контрастности, для которых присутствует медиа-характеристика ) для медиа-запросов, которая похожа на -ms-view-state, которая рассматривается в Главе 6 курса "Введение в разработку приложений для Windows 8 с использованием HTML, CSS и JavaScript". Эта характеристика может принимать значения active (для применения данного правила ко всем темам с высокой контрастностью), black-on-white (тема с белым фоном), white-on-black (тема с черным фоном), и none. Очевидно, none означает, что вы не используете -ms-high-contrast для группировки любых правил; active так же подразумевает, что вы используете -ms-high-contrast без значения. В следующем разделе мы рассмотрим их более подробно.
Как и в случае с состояниями просмотра, вы можете использовать прослушиватели медиа-запросов и ) который указывает на то, разрешено ли переопределять обычные свойства CSS элемента для целей высокой контрастности. Значение по умолчанию, auto, это позволяет; значение none предотвращает такое поведение. Опять же, скоро мы это увидим.
Далее, WinRT представляет текущие установки контрастности посредством класса ). У него есть два свойства: ), код здесь весьма прост:
var accessibilitySettings = new Windows.UI.ViewManagement.AccessibilitySettings();
id("highContrast").innerHTML = accessibilitySettings.highContrast;
id("highContrastScheme").innerHTML = accessibilitySettings.highContrast ?
accessibilitySettings.highContrastScheme : "undefined";
WinRT так же предоставляет подробную информацию о цвете посредством метода ). (Обратите внимание на странный регистр символов в uIElementColor, артефакт результатов проекции WinRT-имен в JavaScript.). Он возвращает объект ) для элемента, идентифицируемого с помощью ). Сценарий 1 примера о работе с контрастностью показывает все эти возможности на примере поучительного, но довольно скучного кода, который я здесь дублировать не буду.
Объект AccessibilitySettings, кроме того, поддерживает одно событие, highcontrastchanged, которое позволяет вам узнать, когда включена или выключена высокая контрастность. Его eventArgs.target является объектом AccessbilitySettings, который содержит свежие данные. Вы можете использовать это событие для вызова любого необходимого программного обновления, которое нужно выполнить в вашем пользовательском интерфейсе, например, для перерисовывания элемента canvas с использованием высококонтрастных цветов, если вы не используете для этой цели прослушиватель медиа-запроса.
Наконец, и для растровых и для векторных изображений применяется соглашение об именовании фйлов, которое используют вместе с суффиксами .scale-100, .scale-140, и .scale-180 для обозначения плтности пикселей. Суффиксы для контрастности – это: .contrast-standard, .contrast-high, .contrast-black (чёрное на белом), и .contrast-white (белое на черном). Мы увидим всё это в действии в разделе "Ресурсы для схем высокой контрастности" ниже, и увидим, как комбинировать суффиксы масштаба и высокой контрастности в разделе "Масштаб + контраст = Квалификаторы ресурсов"
Пример "CSS-стилизация для режима высокой контрастности" (http://code.msdn.microsoft.com/windowsapps/High-Contrast-b36079d8) предоставляет рассмотрение ценного подхода по работе с режимами высокой контрастности, где используются медиа-запросы и файлы изображений. Как вы можете ожидать, основное количество этих возможностей показано в виде декларативных CSS-объявлений и ресурсов приложения. Лишь один сценарий содержит JavaScript-код!
Сценарий 1 показывар разрицу между элементами, которые учитывают использование схемы высокой контрастности и элементами, коорые этого не делают. При использовании обычной цветовой схемы, все три кнопки выглядят так, как показано ниже, где первые две – это элементы div, а третья – это настоящий элемент button.
Когда включается высокая контрастность (Левый Shift+Alt + Print Screen очень удобно переключают режимы при работе с этим примером), они выглядят так:
Первый элемент управления, не учитывающий использование схемы высокой контрастности, всё еще использует белый цвет для границы, которые, конечно, исчезают на белом фоне. Вторая кнопка, с другой стороны, имеет стили, которые используют цвета, заданные системой, связанные с медиа-запросом для режима высокой контрастности, в итоге кнопка нормально работает при использовании любой темы (css/scenario1.css):
@media (-ms-high-contrast) {
.s1-hc {
background-color: ButtonFace;
color: ButtonText;
border: 1px solid ButtonText;
}
/* ... */
}
Совет. Если решили полностью положиться на системные цвета, и в CSS, и в SVG, тогда вы можете вовсе не использовать медиа-запросы или различные SVG-файлы, так как их цвета будут настроены для темы с высокой контрастностью автоматически. Смотрите материал "Системные цвета" (http://msdn.microsoft.com/library/ie/aa358804.aspx). Так же вы можете использовать значение current-Color в SVG для свойств fill, stroke, stop-color, flood-color, и lighting-color для отражения параметров контрастности.
Сценарий 2 показывает похожие эффекты с кнопками, которые используют SVG-изображения для фона. При обычных установках эти кнопки выглядят так:
После включения схемы высокой контрастности они выглядят так:
Всё, что здесь происходить, это использование медиа-запроса для использования, когда это необходимо, высококонтрастного фонового изображения для кнопки:
.s2-button-hc-bg-svg {
background-image: url(../button-not-aware.svg);
background-size: 100% 100%;
width: 200px;
height: 200px;
}
@media (-ms-high-contrast) {
.s2-button-hc-bg-svg {
background-image: url(../button.contrast-high.svg);
background-repeat: no-repeat;
background-size: cover;
}
}
Если вы просмотрите файл ), который будет автоматически подстроен под параметры высокой контрастности).
Что происходит с первой и со второй кнопками? Если вы посмотрите в CSS (css/scenario2.css), вы увидите, что единственное различие заключается в том, что класс стиля для первой кнопки, ), включение высокой контрастности переопределяет большинство цветовых стилей, как и background-image, в последнем случае просту удаляя это изображение. Поэтому первая кнопка отображается пустой. Вторая кнопка имеет правило, определяющее background-image в медиа-запросе, в итоге, фоновое изображение выводится.
Это приводит нас к цели использования стиля -ms-high-contrast-adjust. По умолчанию он установлен в значение auto, позволяя переопределять CSS-свойства. Если мы установим его в значение none в правиле стиля, мы предохраним эти стили от переопределения или настройки. Таким образом, если вы добавите -ms-high-contrast-adjust: none; к правилу .s2-button в css/scenario2.css, вы увидите, что первая и вторая кнопка ведут себя одинаково. Вы можете видеть это изменение в копии примера, в дополнительных материалах к лекции.
Переходим к Сценарию 3, он, в обычном режиме, рисует логотип Internet Explorer в элементе canvas в цвете (левое изображение ниже), в то время как в модели высокой контрастности он рисует логотип в черно-белом варианте (правое изображение):
В данном случае параметры высокой контрастности берутся в JavaScript (js/scenario3.js) с использованием прослушивателя медиа-запроса; CSS здесь не используется (этот код упрощен, для большей понятности, в реальном примере так же производится обнаружение схемы высокой контрастности при запуске приложения):
var fillStyleOuterColor = "rgb(9, 126, 196)";
var fillStyleInnerColor = "rgb(255, 255, 255)";
var mql = matchMedia("(-ms-high-contrast)");
mql.addListener(updateColorValues);
function updateColorValues(listener) {
if (listener.matches) { fillStyleOuterColor = "ButtonText"; fillStyleInnerColor = "ButtonFace";
draw();
}
else {
fillStyleOuterColor = "rgb(9, 126, 196)";
fillStyleInnerColor = "rgb(255, 255, 255)";
draw();
}
Обратите внимание на то, что событие AccessibilitySettings.onhighcontrastchanged можно использовать вместо прослушивателя медиа-запроса.
Элемент canvas – это лучший выбор? В данный момент в приложении "Here My Am!" я использовал изображения для вывода сообщений в элементы img, когда фотография или карта были недоступны. Учитывая нужды работы со схемами высокой контрастности и локализованных вариантов этих изображений, проще взять локализованный строковой ресурс, как мы рассмотрим ниже, и просто создать изображение "на лету" с помощью элемента canvas. Это устраняет необходимость иметь множество различных файлов изображений и уменьшает размер пакета приложения, и, кроме того, полностью соответствует нуждам обеспечения доступности приложения и локализации. Версия "Here My Am!" для этой лекции теперь работает именно так.
В предыдущем разделе, в примере CSS-стилизация для режима высокой контрастности" (http://code.msdn.microsoft.com/windowsapps/High-Contrast-b36079d8) мы столкнулись с соглашениями об именовании файлов, которые загрузчик ресурсов Windows использует для схем высокой контрастности: button.contrast-high.svg, например. Сценарий 4 этого примера показывает, как разрешение таких имен может происходить автоматически. В проекте имеется файл, названный button.svg, вместе с еще одним, который называется button.contrast-high.svg, и с элементом img, который объявлен в html/scenario4.html:
<img src="../button.svg" />
Если система исполняется с нормальными параметрами контрастности, загрузчик ресурсов разрешает это URI в button.svg. (Конструкция ../ используется потому что страница сценария находится на один уровень ниже папки HTML). Когда применены настройки высокой контрастности, загрузчик ищет то же имя файла, но с .contrast-high, вставленным перед расширением.
Примечание. Если вы применяете пользовтельские значки панели приложения (как обсуждалось в Главе 1 курса "Пользовательский интерфейс приложений для Windows 8, созданных с использованием HTML, CSS и JavaScript", не забудьте включить в состав изображений высококонтрастные варианты исходных изображений с использованием данной схемы именования.
Если вы хотите иметь больше параллельных имен файлов, вы так же можете назвать файлы для нормальных настроек контрастности, включив в их имя .contrast-standard, как, например button.contrast-standard.svg. Если вы сделаете это в проекте примера, оставив HTML в том виде, в котором он есть, вы не увидите разницы в выводе данных. В то же время, учитывая особенности поведения системы при работе с контрастностью, рекомендовано использовать .contrast-standard если вы так же поддерживаете варианты .contrast-white и .contrast-black.
Как упомянуто выше, эти варианты применяются автоматически для тем "чёрное на белом" (белый фон) и "белое на черном" (черный фон), соответственно. Для того, чтобы это увидеть, скопируйте файл button.contrast-high.svg, назовите его button.contrast-white.svg, и затем сделайте еще одну копию с именем button.contrast-black.svg. В этой второй копии измените цвета градиента в блоке CDATA, заменив black на ButtonFace. Когда затем вы переключитесь на высококонтрастную тему с черным фоном, вы увидите кнопку в стиле "белое на черном", как это и должно быть.
Все эти изменения можно найти в копии примера, в дополнительных материалах.
Есть одна сложность с элементом img в Сценарии 4, который не обновляется при смене контрастности во время работы приложения, как это происходит с медиа-запросами в Сценариях 1-3. Таким образом, хост-процесс приложения не перерисовывает элемент img в ответ на изменение контрастности. Для того, чтобы изменить это поведение, мы обычно заставляем хост-процесс приложения думать, что изменился URI источника, присоединяя некоторые фиктивные параметры URI. Мы можем сделать это внутри обработчика AccessibilitySettings.onhighcontrastchanged, где eventArgs.target.highContrastScheme предоставляет подходящие переменные для URI (смотрите js/scenario4.js в модифицированном примере):
var page = WinJS.UI.Pages.define("/html/scenario4.html", {
ready: function (element, options) {
var accSet = new Windows.UI.ViewManagement.AccessibilitySettings();
accSet.addEventListener("highcontrastchanged", function (e) {
var image = document.getElementById("buttonImage");
//Используем имя схемы (без пробела) в качестве фиктивного параметра URI
var params = e.target.highContrast ?
"?" + e.target.highContrastScheme.replace(/\s*/g, "") : "";
image.src = "../button.svg" + params;
});
}
});
Одно из значительных преимуществ highcontrastchanged перед прослушивателями медиа-запросов, заключается в том, что последние вызываются очень скоро после того, как произошло изменение, в тот момент, когда загрузчик ресурсов может еще не применить изменения к тому моменту, когда вы устанавливаете атрибут img.src. Это приводит к отображению не тех изображений. Событие highcontrastchanged вызывается гораздо позже, в итоге вышеприведенный код обычно работает. Тем не менее, мои эксперименты в этом направлении (с примером, исполняющимся в прикрепленном режиме и с Панелью управления, открытой в заполняющем), показали, что это не на 100% надёжно: изменение схемы контрастности – это ресурсоёмкая операция, которая вызывает много событий по всей системе, и нет гарантии, что загрузчик ресурсов успеет справиться со своей работой. По этой причине вы можете вы можете решить попросту не пользоваться всем этим, устанавливая явным образом атрибу src для показа известных файлов с конкретными именами. Модифицированный пример действительно использует подобный подход (закомментируйте код выше). Или вы можете просто использовать медиа-запросы!
Так как изображения, с которыми мы работали в предыдущем разделе, имеют формат SVG, нет необходимости поддержки различных файлов для разной плотности пикселей. Но что, если у нас есть растровая графика? Как нам скомбинировать настройки масштабирования и контраста? Об этом так же нужно будет подумать, когда мы будем заниматься локализацией в следующем разделе, так как нам так же может понадобиться использовать разные варианты для разных языков.
Это приводит нас к теме квалификаторов ресурсов (resource qualifiers), во всех подробностях об этом можно прочесть в материале "Как именовать ресурсы, используя квалификаторы" (http://msdn.microsoft.com/library/windows/apps/hh965372.aspx). Квалификаторы включают в себя масштабирование и контрастность, как мы увидим, а так же язык, направление макета, домашний регион и некоторые другие таинственные варианты.
Для того, чтобы скомбинировать квалификатор с отдельным именем файла, присоедините их все вместе, использовав знаки подчеркивания. В общей форме это выглядит как filename.qualifiername-value_qualifiername-value.ext. В итоге, изображение, имеющее имя logo.png, может иметь варианты наподобие logo.contrast-high_scale-180.png и logo.scale-100_contrast-white.png (порядок квалификаторов значения не имеет). Очевидно, с полным набором из трех или четырех вариантов масштабирования (учитывая некоторые случаи использования scale-80) и с четырьмя возможными вариантами контрастности, у нас может получиться 16 разных изображений для одного ресурса.
Образец использования этого механизма можно найти в примере "Ресурсы приложения и локализация" (http://code.msdn.microsoft.com/windowsapps/Application-resources-and-cd0c6eaa). Откройте его в Visual Studio и посмотрите в папку с изображениями. (Хотя пример показывает лишь разные варианты изображений для разных схем контрастности при 100% масштабировании, не забудьте предоставить в собственном приложении варианты для масштаба 140% в 180%; приложение "Here My Am!" для этой лекции поступает так с экраном-заставкой, плитками и логотипом.)
Когда мы займёмся темой подготовки приложения к мировому рынку, мы обнаружим, что локализованные ресурсы изображения требуют набора вариантов с разной контрастностью и масштабированием для каждого языка. Как вы можете догадываться, подобное соглашение об именовании файлов может вызвать путаницу, когда увеличивается количество файлов. К счастью, загрузчик ресурсов позволяет применять квалификаторы в именах папок, в итоге, локализованные ресурсы обычно размещаются в папках, относящихся к конкретным языкам. Больше об этом – ниже, в разделе "Часть 2: структурирование ресурсов для языка по умолчанию". Мы, кроме того, полностью избежали подобных сложностей в приложении "Here My Am!" с помощью использования элемента canvas вместо отдельных изображений для данных графических ресурсов, которые содержат текстовые сообщения (логотип не локализован).
Как и любые другие изображения в вашем приложении, изображения плиток в манифесте, изображения, отправляемые на плитку при обновлении, и изображения, используемые во всплывающих уведомлениях, учитывают установки контрастности. (С индикаторами событий проблемы нет, так как они уже монохромные и настраиваются автматически). Именование файлов изображений в манифесте с использованием квалификаторов ресурсов работает и для настроек масштабирования, и для контрастности, и для языка, как мы увидим ниже.
Полезные данные XML для плиток и всплывающих уведомлений могут ссылаться на локальные изображения с использованием URI ms-appx:///, а загрузчик ресурсов будет искать подходящий файл. Это не применимо, однако, к URI ms-appdata:///, поэтому, если вы работаете с загруженными или динамически генерируемыми изображениями, вам понадобится определять конкретные файлы самостоятельно.
Для полезных данных XML, которые могут ссылаться на удаленные изображения, установка параметра addImageQuery в значение true, как обсуждалось в Главе 2, присоединит к удаленным URI строку запроса, которая отражает масштабирование, контрастность и язык:
?ms-scale=<scale>
ms-contrast=<contrast>
ms-lang=<language>
Подробности об этом можно найти в материале "Глобализация и специальные возможности для уведомлений на плитках и всплывающих уведомлений" (http://msdn.microsoft.com/library/windows/apps/Hh831183.aspx), а так же о том, Как локализовывать строки в полезных данных XML. Мы сами всё это увидим немного позже.
На протяжении многих лет я слышал много слов, описывающих процесс подготовки приложения к различным региональным рынкам, и я могу представить, что вы тоже это слышали: локализация, локализуемость, интернационализация, глобализация и готовность к мировому рынку. Для того, чтобы быть честным, должен заметить, что разница между этими терминами некоторое время была мне не вполне ясна, но я, наконец, нашёл отличное объяснение в довольно старой книге по настольным приложениям, которая называется "Developing International Software", Dr. International (Microsoft Press, 2003). Те же идеи выражены в материале "Глобализация: шаг за шагом" (http://msdn.microsoft.com/en-US/goglobal/bb688110). Таким образом, позвольте мне начать лекцию с простого обзора этой точки зрения.
Цель, которую мы преследуем с помощью приложений для Магазина Windows – сделать их доступными на таком количестве рынков по всему миру, которое доступно в Магазине Windows. Для того чтобы это сделать, приложение нужно написать так, чтобы оно могло приспосабливаться к любому языку и культуре, с которыми оно может столкнуться. В некоторых ситуациях вам понадобиться создавать специальную версию приложения, но, к счастью, у вас может быть одно приложение с локализованными ресурсами, которое работает на большинстве рынков. Действительно, дни одноязычных приложений прошли.
Для того, чтобы достичь этой цели, вы, сначала, должны подготовить приложение к мировому рынку. Готовность к мировому рынку подразумевает, что хотя приложение изначально поддерживает лишь один язык и культуру (весьма вероятно, ваши), оно не делает никаких предположений об этих особенностях в HTML, CSS и JavaScript (и в WinRT-компонентах). Таким образом, основное приложение нейтрально по отношению к языку, культуре и рынку, принимая во внимание следующие факторы:
aria-label и img.alt, выделяется в файл ресурса, таким образом, разные ресурсы могут быть загружены для разных языков. (В наши дни использование текста в формате Unicode стало привычным, поэтому отображение текста на множестве языков – это не проблема, но помните об этом, если вы осуществляете перенос на новую платформу старого программного обеспечения или используете веб-сервисы, которые могут работать иначе).
Приложение, готовое к мировому рынку, коротко говоря, и глобализовано – с использованием API, которые учитывают региональную специфику и легко локализуемо, так как добавление поддержки для других языков не требует изменений кода, а лишь добавление новых строковых и графических ресурсов. Это больше вопрос того, как вы структурируете эти ресурсы, и как вы будете ссылаться на них в разметке и исходном коде приложения.
Процесс локализации, таким образом, это создание или приобретение подобных ресурсов, специфичных для культуры и языка, для чего существуют некоторые весьма полезные инструменты, позволяющие упорядочить работу по переводу.
В следующих разделах мы сначала рассмотрим вопросы глобализации, узнаем, как структурировать ресурсы, чтобы они были локализуемыми, и затем посотрим как работать с локализованными ресурсами. После этого мы готовы будем взглянуть на последний шаг в долгом пути создания приложения: на отправку приложения в Магазин Windows.
Помимо языка, в разных частях мира отличается представление даты и времени (в том числе – календари); представление чисел, мер (единиц), телефонных номеров и адресов; валют; размеров бумаги (об этом мы говорили в Главе 4); есть отличия в том, как сортируется (упорядочивается) текст; отличия в направлении текста и в шрифтах, которые используются для вывода текстов вместе с методами ввода.
Глобализация приложения подразумевает отсутствие предположений о том, как всё это реализуется, вместо этого нужно использовать API WinRT, которые сделают всё как нужно в зависимости от настроек текущего пользователя. И глобализация, преимущественно, означает работу с этими API.
Помимо использования API, посмотрите на само содержимое приложения, проверьте слова, фразы, выражения, которые может быть очень сложно перевести (или на потенциально политически оскорбительные), в особенности разговорные, просторечные, проверьте слэнг, метафоры, жаргон и так далее. Используйте изображения, понятные всем, которые вряд ли могут быть неправильно поняты где-то в мире (представьте себе, что вы носите футболку с подобным изображением в стране, где вы собираетесь продавать приложение!). Проявляйте осторожность при работе с картами, так как имеются разногласия между различными народами о том, где, в действительности, должны быть нарисованы их границы. Лучше ссылайтесь на "страну/регион", чем просто на "страну", так как спорные территории могут не иметь статуса страны.
Кроме того, учитывайте региональные законы, касающиеся экспорта и относящиеся к алгоритмам шифрования, так как вам может быть запрещено делать приложение доступным на некоторых рынках. Посмотрите материал "Ограничения на экспорт средств шифрования" (http://msdn.microsoft.com/library/windows/apps/hh694069.aspx). Кроме того, если вы пишете игру, следует помнить о региональных требованиях по оценке игр, которые могут привести к такому объему дополнительной работы, который выполнять невыгодно. Смотрите материал "Требования к публикации игр в Windows" (http://msdn.microsoft.com/library/windows/apps/hh452788.aspx).
Если вы используете веб-сервисы, убедитесь в том, что вы так же используете сервисы, которые соответствуют региональным особенностям расположения пользователя. Это может быть необходимо по закону в некоторых странах (особенно в том, что касается финансовых операций и карт) и часто гарантирует, что пользователи получают с данного сервиса информацию, соответствующую их региону, если только они не настроят приложение иным образом. Так же вам может понадобиться возможность передать данные о расположении пользователя и его языке подобным сервисам, в итоге, они смогут вернуть содержимое, которое уже локализовано. Кроме того, полезно для общей производительности приложения использовать сервера, которые сравнительно близко расположены к пользователю, чем те, которые находятся по другую сторону земного шара!
Наш первый шаг среди всего этого, однако, заключается в том, чтобы узнать, где, на самом деле, исполняется ваше приложение, узнать язык и культурные предпочтения пользователя. Поэтому давайте посмотрим, как это сделать.
Когда пользователь приобретает устройство под управлением Windows 8 или устанавливает Windows 8 на компьютер, она, вероятнее всего, будет настроена для страны, в которой он живет. Однако, многие пользователи говорят на нескольких языках, независимо от страны проживания и они могут захотеть работать с Windows на конкретном языке, который не имеет ничего общего с их расположением. По этой причине вам всегда следует отдельно рассматривать предпочтения пользователя от реального местоположения устройства, применяя предпочтительные настройки пользователя к тому, как ваше приложение отображает информацию, но использовать физическое расположения для управления тем, какие сервисы вы используете и другими, более функциональными аспектами.
Язык и другие предпочтения настраиваются по адресу Панель управления>Часы, язык и регион (Control Panel>Clock, Language, and Region). Здесь вы можете добавлять языки и выбирать основной (смотрите рис 16.3.), изменять методы ввода, задавать расположение (страну или территорию) и устанавливать форматы даты, времени, чисел и валюты (рис 16.4.)
(рис 16.3) Управление языками в Панели управления
Хорошо, что есть API глобализации, так как иначе иметь дело со всеми возможными здесь вариантами было бы непросто! (Обратите внимание, что изменение форматов на Рис. 6.9. повлияет лишь на те приложения для Магазина Windows, которые исполняются с использованием языка, который вы настраиваете; каждый набор пользовательских форматов относится к конкретному языку).
Основные сведения об установках пользователя доступны посредством объекта ) и через классы в пространстве Windows.Globalization (http://msdn.microsoft.com/library/windows/apps/windows.globalization.aspx). Объект GlobalizationPreferences лишь предоставляет удобные свойства. Четыре из них: ).
(рис 16.4) Диалоговые окна Панели управления для настроек форматов и региона
Кроме того, этот объект содержит строковое свойство, которое называется ). Сценарий 1 примера "Параметры глобализации" (http://code.msdn.microsoft.com/windowsapps/Globalization-preferences-6654eb36) получает и отображает эти данные. Возможно, вы захотите добавить в него код для отображения данных из currencies, так как данные по валюте он не предоставляет. Внеся в него эти изменения и добавив несколько языков в мою систему, я увидел следующее:
Вообще говоря, эти значения, это обычно именно то, что обычно нужно для обмена данными с веб-сервисом, если он предоставляет локализованные данные для приложения. Однако, пользовательские параметры языка лучше получать несколько иным образом, как мы скоро увидим.
Часто нужно знать больше подробностей по каждому из этих параметров, для чего мы можем обратиться к классам пространства имен ), например,просто содержит два строковых свойства: twelveHour и twentyFourHour, значения которых совпадают с тем, что возвращается из ) содержит строковые значения для gregorian, hebrew, hijri, japanese, julian, korean, taiwan, thai, и umAlQura. Таким образом, если вы хотите сравнить календарь, который предпочитает пользователь с каким-то конкретным, вы можете написать такой код:
var userCalendar = Windows.System.UserProfile.GlobalizationPreferences.calendars[0];
if (userCalendar == Windows.Globalization.CalendarIdentifiers.julian) {
// ...
}
При таком подходе ваш код полностью соответствует ключевому принципу глобализации, который касается того, тчо не нужно делать предположения о том, какими могут быть строки календаря.
Другие классы, связанные с глобализацией, несколько богаче по своим масштабам и функция. Класс ), экземпляр которого обычно создают с указанием конкретного тега BCP-47 tag, предоставляет такие сведения, как displayName, nativeName, languageTag, и script. Сценарий 2 вышеупомянутого примера показывает это. Класс Language так же имеет два статических члена. Один из них – это метод isWellFormed, который сообщит вам, содержит ли строка верный тег BCP-47. Второй - это свойство currentInputMethodLanguageTag, которое содержит тег BCP-47 для предпочтительного языка ввода пользователя, который может быть настроен в Панели управления, отличаясь, если нужно, от языка по умолчанию. (Смотрите ссылку Параметры (Options) в правой части Рис. 6.8; так же это показывает Сценарий 4 нашего примера).
Далее, имеется класс ), который, при создании его экземпляра без аргументов, предоставляет подробности о домашнем регионе пользователя. Вы так же можете создать экземпляр, указав конкретную строку для местоположения. В любом случае, он вернет вам displayName, nativeName, множество кодов форматов для региона (code, codeThreeDigit, codeThreeLetter, и codeTwoLetter), и currenciesInUse (массив трехбуквенныех кодов формата ISO 4217). Сценарий 3 примера коказывает эти значения для вашей конфигурации, например, так:
Класс ), в свою очередь, содержит лишь несколько значений. manifestLanguages представляет собой массив языков, определенных в манифесте приложения; вы устанавливаете их при локализации приложения. Объекты languages содержат комбинацию массива GlobalizationPreferences.languages и данных из manifestLanguages. Первый элемент в списке – это наилучшее значение для использования в приложении с учетом предпочтений пользователя, и это значение можно передать веб-сервису для целей локализации.
Далее, это свойство ) и Сценарий 13 примера "Ресурсы приложения и локализация" (http://code.msdn.microsoft.com/windowsapps/Application-resources-and-cd0c6eaa).
Последний класс, Calendar (http://msdn.microsoft.com/library/windows/apps/windows.globalization.calendar.aspx), весьма обширен и содержит слишком много членов, чтобы здесь их перечислять, многие из которых работают с форматированием или выполняют календарные расчеты. Прежде чем этим заняться, однако, давайте посмотрим шире на вопрос форматирования данных.
Если вы осмотритесь в диалоговых окнах для настройки форматов и региона (рис 16.4), вы обнаружите, что возможны тонкие настройки форматирования чисел, которые могут выглядеть пугающе, уже не говоря о форматировании даты, времени и валюты!
К счастью, классы для форматирования в WinRT учитывают все детали, так что вы можете взять значение из new Date(), например, и получить строку, которая полностью отражает предпочтенияп пользователя. Эти API так же предоставляют функции разбора, которые работают в обратном направлении.
В ), ), ), и ), которые следует всегда использовать при конверсии значений данных в строки, которые отображаются в пользовательском интерфейсе. Работа со всеми этими средствами форматирования показана в примере "Форматирование и анализ числовых значений" (http://code.msdn.microsoft.com/windowsapps/Number-formatting-and-bb10ba3d), стандартный рабочий процесс выглядит как создание экземпляра класса со специальным кодом языка или без него, установка необходимых свойств для средства форматирования (таких, как количество цифр и использование разделителей), и затем вызвать его метод format для получения строкового представления данных, или, наоборот, один из его методов parse* для превращения строки в число.
Например, для форматирования значения валюты, создадим объект класса CurrencyFormatter с идентификатором валюты (или с идентификаторов валюты, списком языков и регионом), установим параметры и затем вызовем format (js/CurrencyFormatting.js):
// Применяем значения по умолчанию для пользователя
var userCurrencyFormat =
new Windows.Globalization.NumberFormatting.CurrencyFormatter(userCurrency);
var currencyDefault = userCurrencyFormat.format(fractionalNumber);
// Применяем параметры форматирования валюты
var currencyFormatUSD = new Windows.Globalization.NumberFormatting.CurrencyFormatter("USD");
var currencyUSD = currencyFormatUSD.format(fractionalNumber);
// Применяем параметры валюты, языка и региона (Франции, затем - Ирландии)
var currencyFormatEuroFR =
new Windows.Globalization.NumberFormatting.CurrencyFormatter("EUR",
["fr-FR"], "ZZ");
var currencyEuroFR = currencyFormatEuroFR.format(fractionalNumber);
var currencyFormatEuroIE =
new Windows.Globalization.NumberFormatting.CurrencyFormatter("EUR",
["gd-IE"], "IE");
var currencyEuroIE = currencyFormatEuroIE.format(fractionalNumber);
// Включая дроби с целым числом
var currencyFormatUSD1 =
new Windows.Globalization.NumberFormatting.CurrencyFormatter("USD");
currencyFormatUSD1.fractionDigits = 2;
var currencyUSD1 = currencyFormatUSD1.format(wholeNumber);
// Группируем целые числа
var currencyFormatUSD2 =
new Windows.Globalization.NumberFormatting.CurrencyFormatter("USD");
currencyFormatUSD2.isGrouped = 1;
var currencyUSD2 = currencyFormatUSD2.format(fractionalNumber);
Выходные данные этого кода выглядят следующим образом:
Другие средства форматирования чисел выглядят похожим образом, поэтому я предлагаю вам самостоятельно ознакомиться с примером и документацией.
Для форматирования даты и времени мы можем обратиться к пространству имен ), где можно найти класс ) вместе со множеством перечислений для различных способов форматирования секунд, минут, часов, дней, месяцев и лет. Для использования данного API, вы создаете объект для форматирования, задаете необходимые форматы и применимые языки. (У него не меньше восьми разных конструкторов!). Затем вы выбираете параметры, наподобие ), я думаю, небольшого фрагмента его кода будет вполне достаточно (из Сценария 2, js/stringtemplate.js):
var mydatefmt1 = new Windows.Globalization.DateTimeFormatting.DateTimeFormatter(
"month day");
var mytimefmt1 = new Windows.Globalization.DateTimeFormatting.DateTimeFormatter(
"hour minute ");
var dateToFormat = new Date();
var mydate1 = mydatefmt1.format(dateToFormat);
var mytime1 = mytimefmt1.format(dateToFormat);
Другой фрагмент кода из SDK, который сюда подходит, это пример "Подробные сведения о календаре и вычисления" (http://code.msdn.microsoft.com/windowsapps/Calendar-details-and-math-b1683bb7). Как было упомянуто выше в данной лекции, когда я говорил о времени истечения срока пробной лицензии приложения и покупок из приложения, приложение, готовое для мирового рынка, не должно делать предположений о том, как вычисляются или сравниваются временные отрезки, так как это может различаться в зависимости от регионального календаря. Именн поэтому весьма обширный класс Windows.Globalization.Calendar (http://msdn.microsoft.com/library/windows/apps/windows.globalization.calendar.aspx) содержит десять различных методов add*, которые находятся в диапазоне от addNanoseconds до addEras, вместе с его методами compare и compareDateTime (и множество механизмов для получения текстов, связанных с календарем). Другими словами, навсегда запомните сейчас, что вы никогда больше не будете использовать арифметические операции для работы со значениями даты и времени, так как они не работают соответствующим образом в каждом регионе. Даже в США вы придете к неправильным значениям, так как не учтете что-то вроде перехода на летнее время, когда число часов в двух днях каждого года, на самом деле, не 24!
Так же, как приложения, готовые к мировому рынку, не могут строить предположения о сравнении значений даты и времени, они не могут делать и предположения о том, как сортируются строки. Проще говоря, каждый язык имеет свой собственный способ сортировки, который не обязательно имеет что-то общее со значениями кодов символов. Суть здесь в том, что вам никогда не следует выполнять сортировку по подобным значениям, всегда вместо этого используйте API, учитывающие языковые особенности.
Для приложений для Магазина Windows, написанных на HTML, CSS и JavaScript, вы можете использовать метод ), который уже встроен в строки (даже для отдельных символов). Он производит сравнение, основываясь на текущем языке пользователя. Вы так же можете использовать методы строк ) и ). В Главе 5 курса "Введение в разработку приложений для Windows 8 с использованием HTML, CSS и JavaScript", в разделе, посвященном примеру группировки элементов ) для правильной группировки по первым символам заголовков элементов. Вы можете сравнить исходный пример в SDK с модифицированным примером, который находится в дополнительных материалах к вышеупомянутой лекции, для того, чтобы увидеть, как этот код был глобализован.
Благодаря ), то можете увидеть, что страницы вроде html/scenario2.html содержат подобную разметку:
<div id="scenario2Document">
<h2 lang="hi" id="scenario2Heading" contenteditable="true">
?????? ????? ????????
</h2>
<p lang="hi" contenteditable="true">
?????? ????? ???????? ??? ???? ???? ???? ?????? ????? ????? ???? ??????
???????? ???????? ???? ???? ???? ???? ???? ????? ???? ????? ???????
????????? ???? ???? ????? ?????????? ??? ?????? ?????????? ????????
??? ???? ???? ????? ??????? ??????? ???? ?????? ????? ???? ?????? ???????
???? ???? ????? ????? ???? ??? ???? ???? ????? ????? ????
</p>
</div>
Вот как это выглядит (и если вы читаете на Хинди, вы увидите, что это бессмысленный текст):
Что этот пример, на самом деле, демонстрирует, так это использование объекта ), который предоставляет особые рекомендации по шрифтам для различных частей пользовательского интерфейса. Созданный с использованием конкретного тега BCP-47, объект содержит множество свойств, каждое – типа LanguageFont, как, например, uITextFont и uIHeadingFont (снова обратите внимание на странное изменение регистра). Каждый объект LanguageFont, в свою очередь, содержит такие свойства, как fontFamily, fontStretch, fontStyle, fontWeight, и scaleFactor. С помощью пары вспомогательных функций в js/langfont.js, которые расположены в пространстве имен WinJS.UI , не являясь частью WinJS, эти рекомендации применяются к элементам DOM путём простой установки соответствующего стиля для этих элементов.
Вам должно быть понятно, что эти рекомендации шрифтов – лишь улучшения и в них нет необходимости для реализации базовой функциональности. Как показывает Сценарий 4 примера, базовый английский шрифт (c Unicode-символами, конечно), примененный к смешанному английско-японскому тексту, выводит японский текст, но, возможно, неоптимально. Применение рекомендованного шрифта выполняет такое улучшение.
Другой аспект, касающийся работы с различными шрифтами и языками заключается в том, как всё это влияет на общий макет приложения. Этому посвящен материал документации "Настройка макета и шрифтов для различных языков и поддержка макетов с написанием справа налево" (http://msdn.microsoft.com/library/windows/apps/hh967757.aspx), однако, позвольте мне сделать сводку по этому материалу и добавить кое-что еще.
Во-первых, приложения, готовые к мировому рынку, оставляют дополнительное место для различных фрагментов содержимого, наподобие заголовков и подписей, так как слова и фразы длиннее в некоторых языках и короче в других. Общее правило – оставлять как минимум на 30% больше места, чем вам нужно для строк на английском, и до 300% для по-настоящему коротких предложений и отдельных слов. Например, английское слово "wrench" (гаечный ключ) переводится на немецкий как "Schraubenschl?ssel"; слово "click" (щелчок) (в этом я доверился Bing Translator), переводится на греческий как "????? ???? ??? ??????." В некоторых случаях вам может понадобиться перенос слов.
Для всех подобных целей вы можете использовать селекторы псевдо-классов :lang()/:-ms-lang() (http://msdn.microsoft.com/library/windows/apps/Hh996886.aspx) в CSS для настройки стилей наподобие width так, как нужно для конкретных языков. Не забудьте протестировать ваше приложение с этими языками, или протестируйте его с использованием псевдо-языка (смотрите "Тестирование с помощью псевдо-языка" далее"
Во-вторых, различные языки располагают текст в направлении, отличном от направления слева направо (и сверху вниз), принятое в английском и во многих индоевропейских языках. Арабский и иврит, например, читаются справа налево (RTL) вместо чтения слева направо. В некоторых символы располагаются сначала сверху вниз, потом – справа налево.
Подготавливая свое приложение для RTL-языков (учитывая, что подобные рынки очень важны), вам следует реализовать в своем макете то, что называется "зеркальным отражением". Это подразумевает реверсирование вашего макета, включая изображение, направление кнопки "Назад", направление анимаций, сдвига содержимого и так далее.
К счастью, HTML и CSS-макеты автоматически реализуют подобное, и таблицы стилей WinJS, ui-light.css and ui-dark.css, соответствующим образом задают стиль CSS direction (http://msdn.microsoft.com/library/windows/apps/hh996832.aspx), как показано ниже (это то, что вам следует использовать на уровне элементов для RTL-языков, а не обычное выравнивание):
html:-ms-lang(ar, dv, fa, he, ku-Arab, pa-Arab, prs, ps, sd-Arab, syr, ug, ur, qps-plocm) {
direction: rtl;
}
На самом деле, ознакомьтесь поближе с таблицами стилей WinJS, и вы найдете много настроек, выполненных для RTL-языков :-ms-lang, в частности, поля и отступы. Поэтому, если вы используете HTML, CSS и JavaScript, в том числе – встроенные элементы управления, основная часть техники зеркального отражения реализуется автоматически. Приложение "Here My Am!", например, просто работает на иврите.
Что касается изображений, то вы можете инвертировать их, применяя стиль ), кое-что мы подробнее рассмотрим в следующем разделе.
Иногда вам понадобится задать обратное направление для некоторой части текста, как при смешивании языков в одном и том же абзаце. Для этого вы можете применить стиль unicode-bidi (http://msdn.microsoft.com/library/windows/apps/hh996988.aspx) вместе с параметром direction. (Заметьте, что цифры обычно нейтральны в смысле направления, они принимают направление элементов, которые их содержат, поэтому вам может понадобиться установить параметры направления их расположения отдельно). Аналогичным образом, вы можете так же использовать стиль -ms-writing-mode (http://msdn.microsoft.com/library/windows/apps/Hh997001.aspx) для того, чтобы задать практически любое направление текста, например, для представлений классической китайской, японской или корейской поэзии
Как только ваше приложение было подготовлено к мировому рынку, это означает, что оно может поддержать практически любой язык и региональные установки, которые вы ему передадите, следующий шаг заключается в том, чтобы убедиться, что языкозависимые ресурсы в приложении чётко отделены от HTML, CSS и JavaScript, и размещены там, где их может найти средство загрузки ресурсов Windows (так же упоминаемое как Система управления ресурсами, Resource Management System).
Прежде чем продолжать, вот отличный материал в документации по этой теме: "Подготовка к локализации" (http://msdn.microsoft.com/library/windows/apps/hh967759.aspx), который содержит советы по переводу и другие подробности. Непродуктивно повторять всё это здесь, конечно, поэтому я, вместо этого, хочу разбить руководство на два шага, которые вы можете реализовать для своего приложения и иго языка по умолчанию прежде чем добавлять поддержку дополнительных языков.
Примечание. Загрузчик ресурсов поддерживает разреженную локализацию (sparse localization) для языков, между которыми имеются лишь небольшие различия. Это значит, что при работе с языками, наподобие американского английского (en-US) и британского английского (en-GB), большая часть ресурсов приложения может быть назначена en-US, в то время, как en-GB-ресурсы будут отражать различия, вроде "color" и "colour", "favorite" и "favourite" или наоборот. Так как каждый ресурс разрешается индивидуально, в соответствии с предпочтениями пользователя, приложение, выполняющееся в контексте языка en-GB обнаружит специфические данные, а в противном случае загрузчик использует ресурсы для языка en-US. Существует так же поддержка работы с языковыми исключениями, с помощью ресурсов отмеченных неопределенным тегом und. Смотрите материал "Управление языковыми и региональными параметрами" (http://msdn.microsoft.com/library/windows/apps/Hh967758.aspx), шаг 4 (ближе к концу) и материал "Сопоставление языков" (http://msdn.microsoft.com/library/windows/apps/jj673578.aspx).
Первый шаг в подготовке к локализации заключается в переносе строк, зависимых от языка или региона, из исходного кода в файлы строковых ресурсов и вставка ссылок на данные файлы там, где это нужно. В следующем разделе мы зададим структуру папок для этих файлов и ресурсов изображений, которые будут использованы в локализованной версии.
Для того, чтобы создать ваш первый файл строковых ресурсов, щёлкните правой кнопкой по вашему проекту в Обозревателе решений Visual Studio, выберите команду Добавить>Создать элемент (Add>New Item), и затем выберите Файл ресурсов (Resources File) (.resjson). Хотя вы можете изменить имя файла, просто оставьте его сейчас в значении по умолчанию resources.resjson. Нажмите Добавить (Add), и файл будет создан в корневом разделе вашего проекта, где он и будет оставаться до Части 2.
С опущенными комментариями, которые находятся в верхней части, этот файл выглядит так:
{
"greeting" : "Hello World!",
"_greeting.comment" : "This is a comment to the localizer"
}
Как видите, файл – это обычны JSON, где каждое свойство имеет строковой идентификатор и строковое значение. Любой resjson0 файл может иметь столько свойств, сколько нужно.
Очевидна так же и взаимосвязь между двумя вышеприведенными записями. Первая, в форме
<identifier> : <value>
это реальный строковой ресурс, который задает соответствие действительного JSON-идентификатора(пробелы не применяются) строковому значению. Это то, что загрузчик ресурсов использует для замены ссылки на идентификатор строковым значением.
Любая запись, которая начинается с символа подчеркивания, такая, как обычно применяемая
<_identifier.comment> :<value>
игнорируется загрузчиком ресурсов. Подобные записи предоставляют заметки для переводчика, чтобы он полностью понимал, как используется строка, и то, какие её части не следует переводить. Второй необязательный тип записей, это
<_identifier.source> : <value>
который предоставляет исходную строку на языке по умолчанию, что очень полезно для справочных целей.
Если вы хотите взглянуть на более обширные файлы resjson, откройте пример "Ресурсы приложения и локализация" (http://code.msdn.microsoft.com/windowsapps/Application-resources-and-cd0c6eaa) и посмотрите в папку strings для конкретного языка. В файле ja/resources.resjson, например, вы увидите строковые ресурсы вместе с комментариями и исходными текстами записей:
{
"displayName"
: "???????? ???? JS SDK ????", "_displayName.source"
: "Application Resources JS SDK Sample", "_displayName.comment"
: "Don't change 'SDK'",
"description"
: "???????? ???? JS SDK ????", "_description.source"
: "Application Resources JS SDK Sample", "_description.comment"
: "Don't change 'SDK'",
}
Возвращаясь к вашему собственному приложению и имея новый файл resources.resjson, мы готовы продолжать, выполнять поиск и замену в проекте приложения, искать локализуемые строки, извлекать их в ресурсный файл и заменять их в исходных файлах соответствующими ссылками. Три основных места, которые нам нужно просмотреть, это ваши HTML-файлы, JavaScript-файлы и манифест приложения. Для целей демонстрации, я показал, что я сделал в приложении "Here My Am!", с которым мы работаем на протяжении курса (к нему я добавил файл resources.resjson).
Примечание. CSS-файлы могут содержать страковые литералы в стилях content и quotes; однако, разрешение ресурсов из CSS-файлов для приложений для Магазина Windows в Windows 8 не поддерживается. Локализация в CSS должна быть выполнена с помощью псевдо-селекторов :lang и :-ms-lang.
JavaScript. Начнем с JavaScript, где вам нужно просмотреть код в поиске строковых литералов, включая те, которые выводятся в элемент canvas. В "Here My Am!" я нашёл лишь пару локализуемых строк, а именно, имя папки, используемое в Библиотеке изображений, а так же – заголовок и описание, используемое при форматировании текста для контракта Общий доступ и динамических плиток: (pages/home/home.js):
var folderName = " HereMyAm ";
data.properties.title = " Here My Am! ";
return "At latitude " + lat + ", longitude " + long
return "At (" + lat + ", " + long + ")"
А так же команды для раздела Параметры в js/default.js:
app.onsettings = function (e) {
e.detail.applicationcommands =
{
"about": { title: "About", href: "/html/about.html" },
"help": { title: "Help", href: "/html/help.html" },
"privacy": { title: "Privacy Statement", href: "/html/privacy.html" }
};
WinJS.UI.SettingsFlyout.populateSettings(e);
};
Обратите внимание на то, что в home.js строки на английском используются для показа информации об исключениях, но так как они нужны лишь для отладочных целей, их локализовывать не нужно.
После извлечения других строк в файл resources.resjson, мы приводим его к следующему виду, где я использовал обычные комментарии для того, чтобы указать на то, где используется строка. Обратите внимание на то, что я использовал форматную строку при создании описания местоположения для чудо-кнопки Общий доступ и плиток, вместо того, чтобы задавать эту конструкцию в коде (смотрите функцию formatLocation в js/home.js для того, чтобы увидеть, как это используется):
{
// pages/home/home.js
"foldername" : "HereMyAm",
"share_title" : "Here My Am!",
"location_formatShort" : "At (%s, %s)",
"_location_formatShort_comment" : "Used to format a short location as in 'At (120, 45)",
"location_formatLong" : "At latitude %s, longitude %s",
"_location_formatLong_comment" :
"Used to format a long location, 'At latitude 120, longitude 45",
// default.js
// Команды панели параметров
"about_command" : "About",
"help_command" : "Help",
"privacy_command" : "Privacy Statement",
}
Настоятельно рекомендую, чтобы вы организовали ваши записи по файлам исходного кода, как здесь, и так же вы можете использовать несколько файлов ресурсов, если хотите, как показано в следующем разделе. Так же будьте осторожны с повторным использованием тех же самых строк, которые появляются в нескольких местах. Если это тот же самый пользовательский интерфейс, отображаемый с тем же самым намерением, то всё нормально, но если контекст использования отличается, лучше дублировать строку, так как на другие языки она может переводиться по-другому. В вышеприведенных ресурсах, обратите внимание на то, что я включил комментарий для location_formatShort, так как слово "At" само по себе, возможно, нуждается в некотором контексте для верного перевода.
Когда строки выделены в виде ресурсов, теперь мы можем использовать загрузчик ресурсов для получения этих строк во время выполнения программы. Это можно сделать двумя способами. Первый – с использованием API WinRT, а именно, ):
var loader = new Windows.ApplicationModel.Resources.ResourceLoader();
var text = loader.getString('location_formatShort');
или, проще, с использованием функции-оболочки WinJS.Resources.getString (http://msdn.microsoft.com/library/windows/apps/hh701590.aspx):
var text = WinJS.Resources.getString('location_formatShort').value;
Это работает и в веб-контексте, где WinRT недоступна (Смотрите Сценарий 12 примера "Ресурсы приложения и локализация" (http://code.msdn.microsoft.com/windowsapps/Application-resources-and-cd0c6eaa) ). Обратите внимание на то, что getString возвращает объект, который содержит свойство value со строкой, а так же свойство lang и флаг empty, указывающий на то, что ресурс не был найден.
Метод WinJS, который записывается в одну строку, очевидно, полезен в случае наподобие наших команд параметров, так как мы можем вызывать его внутри. Таким образом, в нашем коде мы просто заменяем строковые литералы на вызовы WinJS, как, например, в pages/home/home.js:
data.properties.title = WinJS.Resources.getString('about_command').value;
И так, внутри объекта для команд панели чудо-кнопки Параметры:
"about": { title: WinJS.Resources.getString('about_command').value,
href: "/html/about.html" },
Обратите внимание на то, что WinJS, оптимизированный для обычных сценариев, поддерживает загрузку строк лишь на языке пользователя по умолчанию. С другой стороны, класс WinRT ResourceLoader обладает гораздо большей гибкостью и может загружать строки на любом заданном языке. Вам нужно использовать данное API, если ваши нужды превышают то, что предоставляет WinJS.
И это всё, что нужно сделать для JavaScript. Если вы сделали подобные изменения в своем приложение, самое время выполнить команду Построение>Построить решение (Build>Build Solution) в Visual Studio. По этой команде файл ресурсов resources.resjson будет скомпилирован в более эффективный двоичный формат и назван resources.pri, записи, имя которых начинается с символа подчеркивания, отбрасываются. Выполнение периодического построения (без запуска приложения) это хороший подход при работе с ресурсами, благодаря которому вы можете обнаружить любые проблемы в ваших файлах, такие, как дублирование записей или синтаксические ошибки. Затем вы можете запустить приложение для того, чтобы увидеть загрузчик ресурсов в действии – в основном не видя различий между тем, что получилось сейчас, и тем, что было раньше! Не забудьте протестировать все ветви кода, которые были вовлечены в работу, для того, чтобы убедиться, что все строки загружаются соответствующим образом.
Манифест. Обратимся теперь к манифесту, где всё даже проще, так как здесь не используется код. Текстовые фрагменты, которые могут нуждаться в локализации, это следующие:
Пока мы работаем с манифестом, обратите внимание на параметр Язык по умолчанию (Default Language) на закладке Интерфейс приложения(Application UI). Это то, что определяет язык приложения по умолчанию или резервный (fallback) язык, если пользователь запускает приложение с языком, который не поддерживается в ресурсах. Мы так же вернемся к изображениями в манифесте в следующем разделе.
Найдя все строки в манифесте, извлеките их в файл resources.resjson, задав им подходящие идентификаторы. Опять же, если у вас есть какие-то сроки в манифесте, которые соответствуют похожим строкам где-то еще в приложении, тщательно оцените их на предмет того, можно ли использовать для них те же ресурсы. Если вы сомневаетесь, храните их раздельно, так как подобная избыточность незначительна. В случае с приложением "Here My Am!", отображаемое имя приложения и строка, используемая для заголовка главной страницы выглядят одинаково и используются похожим образом, поэтому данные параметры могут ссылаться на один и тот же ресурс.
Для того, чтобы сослаться на ресурсы в манифесте, используйте синтаксис ms-resource:<identifier>. Например, я поместил значение из параметра Интерфейс приложения>Отображаемое имя (Application UI>Display Name) в файл ресурсов и назвал его app_title, в итоге, в данном поле редактора манифеста я просто ввожу ms-resource:app_title. То же самое я делаю для описания и отображаемого имени пакета.
Как только вы выполнили эти изменения, запустите приложение и убедитесь в том, что текст на плитках, если вы используете его, отображается верно. Вы можете временно установить параметр Интерфейс приложения>Показывать имя (Application UI>Show Name) в значение Все значки(All Logos) и проверить, но не забудьте вернуть всё обратно!
Как описано в материале "Глобализация и специальные возможности для уведомлений на плитках и всплывающих уведомлений" (http://msdn.microsoft.com/library/windows/apps/Hh831183.aspx), полезные данных XML для плиток и всплывающих уведомлений испльзуют синтаксис ms-resource: для идентификации строковых ресурсов в текстовых элементов. Это вызовет механизм поиска загрузчика ресурсов при выводе плитки, и это работает независимо от того, было ли отправлено уведомление локально, получено с веб-сервиса или принято в виде push-уведомления. Веб-сервисам лишь нужно использовать соответствующие идентификаторы ресурсов приложения.
Веб-сервис так же может напрямую отправлять локализованные обновления плиток. В таком случае приложение обычно присоединяет строку запроса в URI сервиса, отражающую необходимый язык, обновляя при необходимости эти параметры при изменении языка (смотрите "Чистовая отделка локализации" для того, чтобы узнать подробности). Так же приложение может скомбинировать это с использованием региональных веб-сервисов, что помогает в локализации данных обновлений.
HTML. Последнее место, где нам нужно искать строки, это наш HTML-код, который я оставил напоследок, так как работа с ним сложнее, чем другая. Работая с HTML нужно внимательно очистить разметку от любых заданных в ней текстов, которые видимы в пользовательском интерфейсе. Проверьте основное содержимое таких элементов, как p, h1, span, div, button, option, и так далее, так же, как и значения атрибутов title, alt, aria-label, и так далее. Кроме того, посмотрите в элементах управления WinJS, наподобие панели приложения и всплывающих элементов на предмет любых встроенных в них URI, которые вам хотелось бы локализовать, включая ссылки на сервисы, которые вы используете и на содержимое, которое вы показываете в iframe. Обратите внимание, что элементы title в заголовке страницы не отображаются, поэтому не нуждаются в локализации.
В приложении "Here My Am!" я обнаружил множество строк в pages/html/home.html, которые я выделил:
<header id="header" aria-label="Header content" role="banner">
<section id="section" aria-label="Main content" role="main">
<div id="photoSection" class="subsection" aria-label="Photo section">
<h1 class="titlearea win-type-ellipsis">
<span class="pagetitle">Here My Am! (8)</span>
</h1>
<h2 class="group-title" role="heading">Photo</h2>
<img id="photo" class="graphic" src="/images/taphere.png"
alt="Tap to capture image from camera" role="img" />
<div id="locationSection" class="subsection" aria-label="Location section">
<h2 class="group-title" role="heading">Location</h2>
<div id="floatingError" class="win-type-x-large">
Unable to obtain geolocation; check
<br />permissions and use the app bar to try again.
</div>
<div id="retryFlyout" data-win-control="WinJS.UI.Flyout" aria-label="Trying geolocation"
data-win-options="{anchor: 'mapDiv', placement: 'bottom', alignment: 'center'}">
<div class="win-type-large">Attempting to obtain geolocation...</div>
</div>
Где я так же заметил, что мне нужно локализовать изображение taphere.png, так как оно содержит текст, но это в следующем разделе. В default.html, я так же обнаружил подписи и всплывающие подсказки в атрибутах data-win-options команд Панели приложения (для краткости я опустил часть разметки):
<div id="appbar" data-win-control="WinJS.UI.AppBar" data-win-options="">
<button data-win-options="{id:'cmdPickFile', label:'Load picture', icon:'browsephotos',
section:'global', tooltip:'Load a picture through the file picker'}">
</button>
<button data-win-options="{id:'cmdRecentPictures', label:'Recent pictures', icon:'pictures',
section:'global', tooltip:'Browse recent pictures taken in the app'}">
</button>
<button data-win-options="{id:'cmdRefreshLocation', label:'Refresh location', icon:'globe',
section:'global', tooltip:'Refresh your location'}">
</button>
</div>
Совет. Подготавливаясь к локализации, выясните, имеют ли значки на Панели приложения универсальное значение. Если нет, их так же нужно локализовать. К счастью, значения значков имеют строковой формат и могут быть локализованы, в таком случае их нужно воспринимать так же, как подписи и всплывающие подсказки.
Другие файлы в приложении, которые требуют внимания, это все файлы в папке HTML, которые используются для панели чудо-кнопки Параметры. Работая с подобными командами, будьте особенно внимательны с короткими заголовками подписей, которые могут быть элементами div среди другого кода. Не упустите ничего!
Как только вы найдете строки, скопируйте их, как и ранее, в resources.resjson. Работы по копированию и вставке может быть довольно много, поэтому соберитесь с духом и сделайте это. В подобных строках может быть и HTML – он просто добавляется в разметку и выводится так же, как если бы вы присоединили его к свойству наподобие innerHTML, но не включайте туда окружающие теги (скоро они нам понадобятся). Например, в html/about.html у меня есть множество элементов p с текстом:
<p>Here My Am!<br />Version 1.0.0.0<br /></p>
Для данного элемента я создал такую стоку в файле ресурсов (без тега p):
about1" : "Here My Am!<br />Version 1.0.0.0<br />",
А теперь самое интересное: как сослаться на строковой ресурс в разметке. Если вы немного подумаете, то окажется, что нам может понадобиться запустить некий код, который просмотрит разметку и заменит ссылки, которые мы сделали, на соответствующие строки ресурсов. Хм. Не видели ли мы что-то подобное раньше? Да, на самом деле. Работая с элементами управления, мы добавляли в разметку атрибуты data-win-control и использовали WinJS.UI.processAll или WinJS.UI.process для выполнения кода по созданию экземпляров элементов управления. У нас есть нечто подобное и для ресурсов: атрибут data-win-res и WinJS.Resources.processAll, последний должен быть вызван в методе ready каждой страницs или где-нибудь еще при загрузке HTML-содержимого, например, для Панели приложения, например, в обработчике активации приложения после WinJS.UI.processAll (то есть, экземпляры элементов управления уже будут созданы).
Вот, что нужно сделать в разметке:
data-win-res="{<attribute>
: '<identifier>
'}" где <attribute>
это исходное имя атрибута, а <identifier>
соответствует желаемой строке в файле ресурсов и заключен в одинарные кавычки.
<attribute> :'<identifier>' с помощью запятой.
textContent для элементов div, p, или span. Если строка содержит разметку, используйте вместо этого innerHTML, но только по необходимости, так как textContent гораздо быстрее.
{attributes: {'<attribute>
' :'<identifier>
'}} в значении data-win-res, используя одинарные кавычки вокруг <attribute>
. С помощью такого подхода можно скомбинировать локализацию и реализацию специальных возможностей.
data-win-options, разместите их в data-win-res с использованием синтаксиса {winControl: {<property>
: '<identifier>
'}}. Несколько свойств, опять же, разделяются запятыми во внутренних фигурных скобках { }.
Вот примеры модификации разметки, приведенной ранее:
| Исходная разметка | Измененная разметка |
|---|---|
<img id="photo" class="graphic" src="/images/taphere.png" alt="Tap to capture image from camera" role="img" />
|
<img id="photo" class="graphic" src="/images/taphere.png"
data-win-res="{alt: 'photo_alt'}" role="img" /> |
<span class="pagetitle">Here My Am! (8)</span>
|
<span class="pagetitle"
data-win-res="{textContent : 'app_title'}"></span>
|
<div id="locationSection" class="subsection" aria-label="Location section">
|
<div id="locationSection" class="subsection" data-win-res="{attributes: {'aria-label' :
'aria_location'}}" >
|
<div id="floatingError" class="win-type-x-large">
Unable to obtain geolocation; check<br />permissions and use the app bar to try again. |
<div id="floatingError" class="win-type-x-large" data-win-res="{innerHTML : 'error_obtaingeoloc'}"> |
<button data-win-control="WinJS.UI.AppBarCommand" data-win-options="{id:'cmdPickFile',
label:'Load picture', icon:'browsephotos', section:'global',
tooltip:'Load a picture through the file picker'}">
|
<button data-win-control="WinJS.UI.AppBarCommand" data-win-options="{id:'cmdPickFile', icon:'browsephotos', section:'global'}"
data-win-res="{winControl: {label : 'appbar_label1',
tooltip : 'appbar_tooltip1'}}">
|
Когда WinJS.Resources.processAll обходит DOM, он, на самом деле, не удаляет атрибуты data-win-res attributes; он лишь обрабатывает их значения и добавляет к элементам другие атрибуты, которые содержат строковые ресурсы. Преимущество подобного подхода заключается в том, что последующий вызов processAll пройдёт по DOM и обновит все эти строки. Это означает, что если вы обрабатываете событие WinJS.Resources. oncontextchanged, которое сообщает вам об изменении языка, вы можете снова вызвать processAll и ваш пользовательский интерфейс будет отображен с использованием нового языка! Мы добавим этот код позже, когда мы добавим в приложение "Here My Am!" еще несколько языков.
Это так же означает, что если вы хотите произвести привязку данных WinJS, используя строки, которые соответствуют вашим ресурсам, просто включите атрибуты ) (html/scenario8.html and js/scenario8.js):
HTML: <p id="messageCount" data-win-res="{innerHTML: 'scenario8MessageCount'}">
Resources: "scenario8MessageCount" : "You have <span
data-win-bind=\"innerText:count\"></span> message(s)",
И с помощью этого (исключая последующей врезки, которую я добавил ниже), мы готовы к следующему шагу, к работе с графическими ресурсами и к локализации всего того содержимого, которое мы извлекли.
Во всем этом та часть разметки, которая предназначена для HTML-страниц всплывающих элементов для настройки параметров, а именно, about.html, help.html, и privacy.html в папке проекта HTML, вызывает наибольшую сложность. Эти страницы не загружаются до тех пор, пока не будет активирована чудо-кнопка Параметры, и так как это происходит в WinJS, мы можем использовать событие всплывающего элемента beforeshow для вызова WinJS.Resources.processAll для разметки всплывающего элемента. Для того, чтобы перехватить это событие, я добавил onbeforeshow : beforeShow в каждую строку data-win-options и затем данный код с тегом script в конце элемента body:
function beforeShow() {
WinJS.Resources.processAll();
}
beforeShow.supportedForProcessing = true;
Последняя строка здесь необходима, так как WinJS вызовет WinJS.UI.processAll когда страница будет загружена. В любом случае, это хорошо работает для строковых ресурсов, с одним исключением. В privacy.html, (подробнее об этом – в Главе 2 курса "Пользовательский интерфейс приложений для Windows 8, созданных с использованием HTML, CSS и JavaScript"), я использовал iframe для загрузки удаленной страницы с соглашением о конфиденциальности. Так как и она должна быть локализована, я разместил URI в строковые ресурсы и попытался загрузить его как и прочие строки:
<!-- Это не работает -->
<iframe data-win-res="{src : 'privacy_URI'}" height="600"></iframe>
Однако это привело к исключению в WinJS.Resources.processAll, которое сообщало о том, что что-то не было помечено как supportedForProcessing. И что? Только функции так маркируют, и я не мог думать о том, что это относится и к iframe. Оказалось, что элементы iframe специально блокируются в методах WinJS processAll , как и немаркированные функции. В результате, вы просто не можете использовать data-win-res с iframe!
К счастью, простое решение заключается в том, чтобы назначить элементу iframe id (privacyFrame), загрузить строку самостоятельно в обработчике beforeshow и затем установить атрибут iframe.src:
document.getElementById("privacyFrame").src = WinJS.Resources.getString('privacy_URI').value;
В предыдущем разделе мы создали лишь один файл resources.resjson в корневой папке проекта и мы отложили работу с изображениями. Следующий шаг заключается в улучшении структуры проекта, что позволит нам добавлять локализованные ресурсы для дополнительных языков, включая изображения.
Начнем со строк, выполните следующие шаги:
Если сейчас вы снова запустите приложение, вы должны увидеть, что всё работает. Если вы вернетесь к вышеупомянутому материалу "Как именовать ресурсы, используя квалификаторы" (http://msdn.microsoft.com/library/windows/apps/hh965372.aspx), вы увидите, что загрузчик ресурсов совершенно счастлив, если вы используете квалификаторы наподобие кодов BCP-47 в качестве имен папок. Он обычно просматривает все имена папок в поисках квалификаторов, поэтому вы можете создавать более глубокую иерархию для того, чтобы сортировать ресурсы так, как вам хочется. Таким образом, вы можете сначала отсортировать ресурсы по контрасту и масштабированию, если нужно, и включить суффиксы языков в имена файлов (с использованием формата lang-<BCP-47 тег="">). Более того, вы можете создать дополнительные файлы .resjson в данных папках и делает еще некоторые интересные вещи. Смотрите врезку "Дополнительные файлы строковых ресурсов".
В любом случае, то что вы сейчас сделали, переместив ваши ресурсы в папку для языка по умолчанию, установленному в качестве резервного языкового ресурса – это то, что загрузчик ресурсов будет обращаться к ним, если он не сможет найти более подходящих ресурсов для текущего языка пользователя. Находить совпадения, это, на самом деле, сложный процесс, где загрузчик ресурсов измеряет нечто вроде "расстояния" между предпочтениями пользователя и доступными ресурсами и выбирает то, что ближе к предпочтениям. Это делает возможным выбрать, например, en-GB как более близкий к en-AU чем en-US. В общем случае, таким образом, это означает, что при поиске для конкретного языка сначала будет использованы ресурсы с квалификатором de-DE (немецкий язык), затем – следующий ближайший язык, использующий квалификатор de, а затем будет осуществлен переход к языку по умолчанию (если нет ресурсов для других языков пользователя). Короткий вывод из всего этого заключается в том, что вам всегда следует помнить о том, что идентификаторам языков, заданным в манифесте, соответствует полный набор ресурсов. Тогда, если даже вы не локализуете некоторые из этих ресурсов (например, для точного соответствия культурным особенностям), хотя бы один из таких ресурсов будет найден). Для получения полного представления по этому вопросу обратитесь к материалу "Сопоставление языков" (http://msdn.microsoft.com/library/windows/apps/jj673578.aspx) в документации.
И WinRT и WinJS могут работать с дополнительными файлами строковых ресурсов (.resjson), позволяя вам, если нужно, организовывать строковые ресурсы в нескольких файлах. Например, строки с сообщениями об ошибках обычно выделяют в файл errors.resjson. Ссылаясь на строковой идентификатор, находящийся в одном из таких дополнительных файлов, всё, что нужно – использовать синтаксис
/<file> /<identifier>
вместо простого ).
С файлами .resjson можно делать и еще кое-что, добавляя в их имена квалификаторы для схем высокой контрастности, масштабирования, указывающие на домашний регион, и так далее, и даже организовывать эти файлы в любой из существующих папок. Это показано в Сценарии 13 того же самого примера, где есть множество разных файлов .resjson в папке strings/scenario13, имя каждого из которых имеет вид scenario13.<qualifiers>.resjson. Так как имя папки не использует стандартных квалификаторов, вам нужно сделать кое-что еще, чтобы со всем этим работать, использовать API Windows.ApplicationModel.Resources.Core.ResourceManager (http://msdn.microsoft.com/library/windows/apps/windows.applicationmodel.resources.core.resourcemanager.aspx), но этим стоит заниматься, если вы настоящий ресурсный наркоман!
В случае с изображениями, мы уже видели, что если у нас есть папка images и размещаете в ней файлы наподобие logo.contrast-high_scale-140.png, вы можете просто ссылаться на файлы с помощью обычного относительного URI, не использующего квалификатор, наподобие /images/logo.png и загрузчик ресурсов найдёт их.
Совет. Потенциальная множественность изображений с различными вариантами масштабирования, контраста, языка, и возможное наличие других изображений (наподобие вариантов для разных направлений), имеют важное значение для пакета приложения: большее количество изображений увеличат размер пакета. Более крупный пакет в Магазине Windows может оттолкнуть некоторых пользователей от загрузки вашего приложения, особенно если они пользуются лимитированными сетями. Таким образом, нужно аккуратно оценить реальную необходимость в изображениях, которые позволят обеспечить вариации различных факторов, особенно это касается больших изображений, и оптимизировать уровень сжатия всех изображений для уменьшения размера пакета. Задайтесь вопросом, нужно ли локализовать ваш экран-заставку – обычно одно из самых больших изображений, особенно в масштабе 180%, и проверьте, хорошо ли выглядит изображение, подготовленное для масштаба в 180%, когда оно масштабируется до 140%, до 100%. Если ваш экран-заставка, другими словами – это лишь изображение с достаточным уровнем контрастности и вы используете на нём универсальное имя приложения, один файл можно будет использовать во всех случаях.
Так же обратите внимание, что нет необходимости предоставлять ресурс без квалификатора, если вы предоставляете все остальные специфические варианты, так как масштабированный вариант всегда будет иметь преимущество над обычным. В результате, ресурсы без квалификаторов в именах просто занимают место в пакете приложения, но никогда не используются.
Для подготовки к локализации, нам нужно лишь переместить изображения в папку для нашего языка по умолчанию, как мы поступали и со строками. Так как вы уже используете относительные URI для того, чтобы ссылаться на изображения (с использованием ms-appx:/// или нет), вы можете использовать любой желаемый путь к папке в качестве корневой папки для изображением. Там, создайте папку с именем, соответствующим подходящему тегу языка BCP-47 и переместите все ваши файлы для языка по умолчанию в эту папку. В приложении "Here My Am!", например, изображения находятся в папке images, таким образом, всё, что нужно сделать – это создать папку en-US в данной папке, переместить в нее все изображения, и все мои ссылки вида /images/tile.png будут продолжать работать. И потому что теперь они находятся в папке, которая соответствует языку приложения по умолчанию, они становятся резервными изображениями.
У мня есть одно изображение, maperror.png, которое расположено в папке pages/home вместе с файлом home.html, который на него ссылается. Я переместил это изображение в папку images/en-US и обновил ссылки URI соответствующим образом (но потом отказался и от него, и от taphere.png в пользу динамического рисования в элементе canvas). Вы можете, конечно, разместить изображения в любом желаемом количестве папок, учитывая, что каждая из них имеет внутри себя папки, соответствующие различным языкам. Возможно, это более удобно, однако, использовать одну корневую папку, или лишь несколько. В случае с "Here My Am!", в конце данного шага у меня было две языковых папки в проекте:
В вашем приложении, соответственно, посмотрите на ссылки на изображения в проекте. В HTML обращайте особое внимание на элементы img. В CSS обращайте внимание на стили background-image. В манифесте посмотрите на закладку Интерфейс приложения (Application UI) (логотипы, значки), на закладку Объявления (Declarations) (еще логотипы), и на закладку Упаковка (Packaging) (логотип для Магазина Windows). В JavaScript, наконец, проверьте любые URI, которые вы могли назначить свойствам элементов или CSS-стилям, так же как и те, на которые вы могли ссылаться в XML для плиток, индикаторов событий и всплывающих уведомлений.
После всего этого проверьте каждое изображение для того, чтобы определить, нуждается ли оно в локализации, включая те, которые должны быть реверсированы для использования в языках с письменностью справа налево (для этих целей вы можете использовать по одной копии для всех RTL-языков, назвав их с помощью квалификатора layoutdir qualifier; посмотрите об этом в материале "Как именовать ресурсы, используя квалификаторы" (http://msdn.microsoft.com/library/windows/apps/hh965372.aspx) ). Изображения, не нуждающиеся в локализации (возможно, изображение для плитки, логотипы, простые графические элементы, которые вы используете в макете), держите в папке резервного языка. Они будут использованы, если другие не подойдут под текущий набор квалификаторов (язык, масштаб, контраст и так далее). Полагайтесь на резервные данные, если только у вас нет других вариантов. В итоге, теперь всё готово для локализации!
Пример "Ресурсы приложения и локализация" (http://code.msdn.microsoft.com/windowsapps/Application-resources-and-cd0c6eaa) показывает множество различных сценариев того, как можно управлять локализованными ресурсами и ссылаться на них. Полезно будет потратить некоторое время на работу с этим примером, так как он использует большую часть того, о чем мы здесь говорили: графические ресурсы (Сценарий 1); строковые ресурсы в HTML, JavaScript и в манифесте (Сценарии 2-4); использование дополнительных файлов ресурсов (Сценарий 5); отправка сведений о языке на веб-сервис (Сценарий 7); комбинацию ресурсов и привязки данных (Сценарий 8); использование ресурсов с именами, содержащими дефис ((Сценарий 9); вызов и обработка изменения язка (Сценарии 10 и 6); переназначение языкового контекста по умолчанию (Сценарий11); использование WinJS для разрешения ресурсов в веб-контексте (Сценарий 12); и многомерные резервные данные ((Сценарий 13).
Примите поздравления! Благодаря всему, что мы сделали в предыдущих разделах, мы должны получить приложение, которое полностью готово к локализации. Всё, что нужно теперь сделать – получить переведенные версии ваших файлов .resjson (для строк, примите к сведению возможность разреженной локализации) и переведенные версии любых необходимых изображений.
Совет. Если у вас есть изображения, которые содержат текст, убедитесь, что у в ваших файлах ресурсов есть строки, соответствующие содержимому изображений, так как их обычно используют в качестве атрибутов alt для изображений. Делая это, вы получаете необходимый перевод для изображений в процессе локализации строк.
Если хотите вы можете просто передать ваши файлы .resjson files, вместе с изображениями, содержащими текст, переводчику или в агентство переводов и предоставить им возможность делать свою работу. Когда вы получите материалы обратно, просто создайте дополнительные папки с кодами BCP-47 в ваших папках strings и images, поместите в них данные файлы и всё будет сделано. Вы увидите подобные структуры в примере "Ресурсы приложения и локализация", о котором мы упоминали ранее.
Ручной перевод может занять много времени и немало стоить. Это, от части, потому что профессиональные переводчики не обязательно имеют инструменты для работы с файлами ресурсов, обходясь текстовыми редакторами. Им хорошо было бы иметь современные инструменты, которые помогали бы им отслеживать состояние работы по переводу и много всего еще, работать с индустриальным стандартом в виде формата XML, известным как XLIFF (XML Language Files). В итоге, это обязывает нас (и наши чековые книжки!) упростить жизнь переводчикам, даже уменьшить объем работы, позволив просматривать связанные переводы вместо того, чтобы делать всю работу с нуля.
Для того чтобы в этом помочь, Microsoft предлагает бесплатный инструмент Multilingual App Toolkit (набор средств для многоязыковых приложений) для Visual Studio 2012 (http://msdn.microsoft.com/ru-rU/windows/apps/hh848309.aspx). Как только вы загрузите и установите набор средств, загрузите ваш проект в Visual Studio и выполните команду Сервис>Включить набор многоязычных инструментов (Tools>Enable Multilingual App Toolkit). Вам нужно сделать это для каждого проекта по отдельности, потому что в этот момент набор средств создает многоязычные ресурсы для вашего приложения – в файле resources.pri даже если вы не добавляли дополнительные файлы .resjson.
Как только вы включили набор инструментов, в меню Проект (Project) добавляется команда Добавить языки переводов (Add Translation Languages). Она вызывает диалоговое окно Языки переводов (Translation Languages), как на рис 16.5, в котором вы выбираете желаемые целевые языки. На самом верху списка будет автоматически активирована опция Псевдоязык (qps-ploc) (Pseudo Language); мы будем использовать его в следующем разделе для тестирования локализации. Это то, что обычно делают перед локализацией. Кроме того, отметьте, что многие языки отмечены логотипом "Microsoft Translator", что означает, что перевод для них можно, по большей части, выполнить автоматически, сберегая время переводчиков и ваши деньги.
(рис 16.5) Первое диалоговое окно набора средств для многоязыковых приложений для выбора языков перевода. Слева можно видеть опцию Псевдо-язык (Pseudo Language), искусственный язык с множеством интересных символов, которые представляют нужды большинства других языков
Видео!
Ниже представлены ссылки на видеоматериалы по набору средств для многоязыковых приложений:
Как только вы выбрали нужные языки (вы можете добавить больше позднее), нажмите ОК, и набор средств создаст в вашем проекте папку с именем MultilingualResources, наполненную множеством XLF-файлов (эти файлы любят переводчики). Поначалу они будут практически пустыми, но сейчас вы увидите, для чего было создавать файл ресурсов по умолчанию. Щёлкните правой кнопкой по проекту в Обозревателе решений и выберите команду Построение (Build) или Перестроить (Rebuild), или выполните аналогичную команду меню. Благодаря этой команде будет осуществлен просмотр ваших строковых ресурсов (в том числе – любых локализованных вариантов, которые вы уже создали) и XLF-файлы будут заполнены вашими строками. В ходе этого процесса так же извлекаются ссылки на ваших изображения, не являющиеся логотипами (изображения плиток и экрана-заставки будут опущены), которые так же, возможно, нужно перевести.
Теперь, для настоящего развлечения, сделайте двойной щелчок по XLF-файлу для того, чтобы загрузить Многоязычный редактор (Multilingual App Toolkit Editor), показанный на рис 16.6. Здесь вы можете управлять тем, какие ресурсы можно или нужно переводить, отслеживать состояние перевода. Если язык так же поддерживается системой перевода Microsoft Translator, в верхней части будет активна кнопка Перевести (Translate) для перевода отдельной записи, а так же – Перевести всё (Translate All). Нажмите последнюю кнопку и сидите, наслаждаясь зрелищем. Через некоторое время вы увидите, что набор средств перевел все строки, пометив их все состоянием Требуется проверка (Needs review), как показано на Рис. рис 16.7.
(рис 16.6) Многоязычный редактор (Multilingual App Toolkit Editor), XLF-редактор со встроенным машинным переводчиком
(рис 16.7) Строковые ресурсы приложения "Here My Am!" после машинного перевода на язык хинди
Как только перевод будет завершен, сохраните файл и закройте редактор, если хотите. Перейдите в раздел Панель управления>Часы, язык и регион>Язык (Control Panel>Clock, Language, and Region>Language) и перенесите целевой язык в верхнюю часть списка языков. Теперь вернитесь в Visual Studio и запустите приложение – и перед вами результаты первого этапа локализации, как показано на рис 16.8. для "Here My Am!" (Обратите внимание на то, что я решил не переводить название программы, менять его чем-то, что предложит переводчик, я сохранил его английское написание из-за его уникальной грамматики).
(рис 16.8) "Here My Am!" на хинди, с использованием машинного перевода. Такой перевод, конечно, следует проверить носителю языка. Как видите, я проверяю, есть ли у Йогананды советы относительно языка
Если вы хотите, чтобы ваше приложение обитало на окраинах и не беспокоитесь о том, чтобы отправлять в Магазин Windows приложение, над которым люди на других рынках могут посмеяться или покритиковать вас за небрежность, тогда ничто вас не останавливает от отправки приложения на такие рынки с машинным переводом, подобным этому. Если же вам больше нравятся хорошие оценки и отзывы, тогда полезно будет найти носителей языка, которые смогут проверить и исправить машинный перевод. И эти полезные люди тоже могут использовать Многоязычный редактор для работы с вашими XLF-файлами. Когда эти файлы будут проверены и возвращены к вам, импортируйте их обратно в Visual Studio, щёлкните правой кнопкой по XLF-файлу в Обозревателе проектов и выберите команду Импортировать переводы (Import Translation). Новый перевод будет включен в состав программы при следующем построении.
Работая с профессиональными переводчиками, вы так же можете использовать специальный формат XLIFF Translation, для этого щелкните правой кнопкой мыши по XLF-файлу в Visual Studio и выберите команду Отправить в перевод (Send for Translation).
Вот еще три замечания об этом процессе. Во-первых, могут быть некоторые строки или части строк, которые не нужно переводить. В Многоязычном редакторе вы можете установить параметр Подлежит переводу (Translatable) в значение Нет (No) для всей строки для того, чтобы машинный перевод не изменял её. В случае с частями строк, они будут переводиться, но вы можете отредактировать их, приведя в нужное состояние, после чего, в поле Комментарий (Comments) сделать соответствующую запись для переводчиков.
Во-вторых, набор средств для многоязыковых приложений может определить, что вы уже сделали перевод в XLF-файле, в результате команды построения проекта не переписывают переведенные строки. В то же время, он импортирует любые новые строки, которые вы могли добавить в файл ресурсов и удаляет те, которые были удалены. Изменение в идентификаторе ресурса обрабатывается как удаление и добавление, то есть, перевод строки будет потерян.
И, наконец, если вы хотите удалить язык, просто щёлкните правой кнопкой по XLF-файлу и выберите Исключить из проекта (Exclude From Project). Это исключит файл из построения проекта, но сохранит файл (и переводы) в папке проекта.
Как бы интересен ни был процесс перевода приложения на многие языки, есть и задача всё это как следует протестировать, весьма трудозатратная задача, если вы используете много языков! Для уменьшения этой нагрузки лучший подход заключается в тестировании вашего приложения с использованием Псевдо-языка (Pseudo Language), шаг, который, в идеале, предшествует оценке стоимости перевода. Он поможет вам проверить, верно ли ваше приложение работает с разнообразными языками, так как вымышленный Псевдо-язык содержит некоторые из наиболее проблематичных характеристик локализованного текста.
Как упоминалось в предыдущем разделе, этот язык автоматически добавляется в проект посредством окна выбора языков средства для многоязычных приложений. Создаётся файл Pseudo Language (pseudo).xlf в папке MultilingualResources, рядом с файлами реально используемых языков. После этого нужно щелкнуть данный файл правой кнопкой мыши и выбрать команду Создать псевдопереводы (Generate Pseudo Translations). Эта команда заполнит XLF-файл переводами ваших ресурсов по умолчанию, где обычные символы будут часто конвертированы в расширенные символы и строки обычно завершаются множеством присоединенных "!!!!!", В итоге, строка наподобие "Recent pictures" будет переведена как "[62BD8][!!_????й? ????µ???_!!!!]" где шестнадцатеричный код в первых квадратных скобках [ ] это идентификатор ресурса, который помогает тестировщику определить реальный используемый ресурс. (Обратите внимание, что этот процесс "переведет" каждую строку, независимо от того, будете ли вы переводить эту строку для реальных целей, так как это полезно для тестирования.).
Для того, чтобы запустить приложение с таким переводом, вам нужно сделать Псевдо-язык языком системы по умолчанию. Перейдите в раздел Панель управления>Часы, язык и регион>Язык (Control Panel>Clock, Language, and Region>Language), нажмите на кнопку Добавить язык (Add Language) и введите qps-ploc в поле поиска. Это единственный способ, благодаря которому появится опция Псевдо-язык (Pseudo Language):
Выбрав этот язык, нажмите Добавить (Add) и переместите его в верхнюю часть списка:
Когда вы запустите приложение, вы должны увидеть, что оно отображается с использованием Псевдо-языка:
Когда ваше приложение исполняется с использованием Псевдо-языка, испытайте каждую возможность и опцию. Проверьте каждую страницу в каждом из состояний просмотра; проверитье все команды панели приложения; проверьте все параметры, сообщения об ошибках, всплывающие окна и диалоговые окна сообщений, которые могут появляться лишь при особом стечении обстоятельств наподобие изменения состояния сетевого соединения. И протестируйте все ветви кода активации в соответствии с используемыми им контрактами. Когда вы сделаете это, посмотрите все строки, которые не отображаются на псевдо-языке, что ясно указывает на то, что вы упустили эти строки в коде или разметке и они локализованы не будут. Кроме того, проверьте обрезанный текст, неожиданные переносы слов и так далее, что позволит понять, где ваш макет не способен нормально разместить переведенные строки.
Это время, когда вы должны быть внимательны, как никогда, так как, как только вы отправите приложение в Магазин Windows, выпуск следующего обновления займёт неделю-две, а в течение этого времени ваши пользователи могут обнаружить эти проблемы, что соответствующим образом отразится на рейтинге вашего приложения. Об этом всегда стоит помнить, особенно, если вы привыкли к мгновенному исправлению ошибок на веб-сайтах: для приложений требуется больше времени, поэтому лучше потратить больше времени на тестирование.
Итак, мы почти завершили работу над приложением и готовы отправляться в Магазин Windows! Осталось лишь упомянуть еще кое-о чем, касающемся локализации:
WinJS.Resources.addEventListener("contextchanged", function () { WinJS.Resources.processAll();
});
Мы прибыли в последний раздел данной лекции и последний раздел курса, совершив полный круг. Пришло время отправки вашего приложения, готового к мировому рынку, в Магазин Windows для того, чтобы сделать его доступным для мира.
Так как процесс отправки приложения хорошо документирован в материале "Продажа приложений" (http://msdn.microsoft.com/library/windows/apps/br230836), я не собираюсь тратить наше время, показывая вам кучу скриншотов Информационной панели (https://appdev.microsoft.com/StorePortals), где всё это выполняется. Я укажу вам на конкретные страницы соответствующих документов, если будет нужно, но это будут разделы документации, которые вам нужно будет просмотреть. В конце концов, Магазин Windows – это канал продажи для ваших приложений, в итоге, вам нужно будет понять этот канал так хорошо, как только возможно. Информационная панель Магазина Windows, кроме того, создана для того, чтобы провести вас через все этапы данного процесса.
То, на чем мы здесь сконцентрируемся, это те аспекты процесса, которые не всегда очевидны, основываясь на реальном опыте, который я и мои сослуживцы получили в Windows Ecosystem Team в ходе работы с первыми партнерами над отправкой приложений в Магазин Windows. Посредством этого я надеюсь повысить ваши знания о возможных проблемах, с которыми вы можете столкнуться, в итоге, вы лучше будете подготовлены к ним. Затем мы поговорим об обновлениях приложения и об увеличении вероятности обнаружения вашего приложения пользователями благодаря его связью с вашим веб-сайтом.
Когда вы создаете пакет вашего приложения для загрузки его в Магазин Windows, не забудьте установить конфигурацию приложения в значение Выпуск (Release) вместо значения Отладка (Debug), иначе оно не пройдёт сертификацию. Выбирая целевую платформу, установите её в значение "Any CPU", если только у вас нет WinRT-компонентов, написанных на C++. Таким образом, JavaScript и .NET-языки (C#/VisualBasic) архитектурно-нейтральны. С другой стороны, всё, аписанное на C++, должно компилироваться под конкретную платформу: x86, x64,и ARM. Чаще всего вам придется создавать три варианта построения для этих архитектур, которые вы будете загружать в Магазин Windows отдельно.
Прежде чем вы сделаете что-то еще, связанное с вашим приложением и Магазином Windows, посмотрите материал "Представление приложения в Магазине Windows" (http://msdn.microsoft.com/library/windows/apps/hh694057.aspx) и дополнительные материалы: "Информация об описании приложения" (http://msdn.microsoft.com/library/windows/apps/hh694060.aspx), "Выбор изображений для вашего приложения" (http://msdn.microsoft.com/library/windows/apps/hh846296.aspx). Кроме того, обратитесь к материалу "Подготовка приложения для отправки в Магазин Windows" (http://msdn.microsoft.com/library/windows/apps/hh694079.aspx), который предоставляет множество ценных сведений о процессах, которые предшествуют отправке приложения, в частности, он содержит ссылки на такие материалы, как "Выбор названия приложения" (http://msdn.microsoft.com/library/windows/apps/hh694079.aspx) и "Что необходимо включить в описание приложения" (http://msdn.microsoft.com/ru-RU/library/windows/apps/hh694076.aspx).
Причина, по которой я указываю эти материалы, заключается в том, что вы уже потратили, или собираетесь потратить много времени и сил на разработку приложения (и на тестирование, как мы обсудим в следующем разделе), и вы должны приложить сравнимые усилия для того, чтобы ваше приложение отлично выглядело в Магазине Windows. Всё то, о чем говорится в вышеупомянутых материалах: название и описание приложения, подробности о приложении, рекламные изображения – всё это составляет первое впечатление пользователей от вашего приложения.
Позвольте мне повторить снова: всю эту информацию потенциальный покупатель будет использовать для оценки вашего приложения до того, как он нажмёт кнопку для того, чтобы получить это приложение. Это маркетинговые материалы, простые и понятные, поэтому пусть они будут просто великолепными! Потратьте некоторое время на написание по-настоящему хорошего текста описания приложения – можете даже передать их профессиональному редактору или нанять профессионального технического писателя. Если вы чувствуете, что ваше приложение забавное и увлекательное, расскажите об этом через тексты и изображения. На самом деле, вы ведь хотите, чтобы первое впечатление пользователя о вашем приложении – после взгляда на страницу приложения – было бы в стиле "Ух ты!". И именно вышеупомянутое содержимое определяет подобную реакцию.
Другая причина, по которой я так настойчиво это выделяю заключается в том, что иначе вы просто не узнаете о том, что вам всё это нужно, до процесса отправки, когда Магазин Windows запросит у вас текст и изображения. Если вы еще не подготовили эти материалы, таким образом, и вы пытаетесь отправить приложение в Магазин Windows так быстро, как только можно, вы, в итоге, столкнетесь с весьма серьезными неприятностями. В результате, первое впечатление от вашего приложения будет далёко не таким хорошим, каким оно могло бы быть.
Сертификат с оценкой игры. Отправляя в Магазин Windows игру, вы должны получить сертификат с оценкой игры в форме GDF-файла. Для того чтобы узнать подробности, смотрите материал "Требования к публикации игр в Windows" (http://msdn.microsoft.com/library/windows/apps/hh452788.aspx).
Если только вы не рождены тестером, тестирование приложения подразумевает меньше сильных впечатлений, чем разработка, однако, оно может сыграть ключевую роль в успехе вашего приложения.
На самом деле, для многих разработчиков, особенно тех, которые сконцентрированы на веб, как я ожидаю, и для мноогих читателей, строгое тестирование не является одним из их ключевых занятий. Я думаю так из-за природы веб-разработки, когда вы можете загрузить на сайт исправление, которое мгновенно возымеет действие, что не требует особой дисциплины в тестировании. Часто ли вы видите, как ваши любимые веб-сайты просто не доступны весь день, или плохо работают несколько часов, а затем снова возвращаются к жизни? Это, возможно, потому что какой-нибудь разработчик допустил неприятную ошибку, которая была обнаружена и исправлена в течение этих часов. Для некоторых сайтов это подобно катастрофе, но для многих других это нежелательно, хотя и не смертельно.
Говоря другими словами, стоимость ошибок в веб-приложениях обычно очень мала, так как время обновления так же очень мало. Но это не так для приложений. Время с момента, когда вы отправляете приложение в Магазин Windows, до того момента, когда оно будет доступно потребителям, это, как минимум, неделя, если не больше, в зависимости от загруженности Магазина Windows. Это означает, что каждая отправка весьма важна.
Посмотрим на это с точки зрения затраченного времени. Скажем, для того, чтобы загрузить исправление для веб-приложения, нужно пять минут. Сравните это с количеством минут в неделе, которых в ней 10800. Каково соотношение? 1 к 2016. Другими словами, это, как минимум в 2000 раз дороже с точки зрения времени и усилий, потраченных на обновление приложения в Магазине Windows. Говоря с практической точки зрения, это значит, что вам придется потратить гораздо больше усилий на тестирование приложений, чем на тестирование веб-сайтов. И не так уж и мало! (И не возражайте, говоря, что вы тратите нулевое время на тестирование веб-приложений, а значит и цена обновления при таком подходе так же равна нулю)
Если у вас нет методологии тестирования, тогда начните её создавать, даже с нуля. Например, не забудьте всегда тестировать ваше приложение на чистой установке Windows 8, на компьютере без лицензии разработчика, а так же на маломощных компьютерах, производительность которых похожа на производительность многих ARM-устройств. У одного из разработчиков, с которым я работал, было приложение, которое было отвергнуто Магазином Windows, так как оно просто было пустым при первом запуске – он никогда не видел, как это происходит из-за кэшированных данных, которые были на его компьютере!
Вам так же нужно построить хороший список того, что нужно делать с вашим приложением, чтобы исполнить все ветви его кода. Это должно включать и учет тех условий, которые являются внешними по отношению к приложению: изменение режимов просмотра и ориентации устройства; активация различных чудо-кнопок; изменение состояния соединения с сетью; работа с медленными каналами передачи данных; удаление временных файлов приложения с помощью средства очистки диска; вход с различными учетными записями; приостановка, возобновление работы и запуск после остановки; работа в высококонтрастных режимах и с другими специальными возможностями; работа в системах с разными языками. Чем лучше ваше приложение ведет себя во всех этих условиях, тем более целостным будут видеть его пользователи, которые пишут отзывы и ставят оценки. Я рассказал об этом в видео, которое называется "Beyond Just Beautiful", которое вы можете найти на странице "Принципы работы и архитектура" (http://msdn.microsoft.com/library/windows/apps/br211361.aspx) в Центре разработчиков.
Помимо этого есть некоторые отличные материалы в документации, которые помогут вам выполнить данные шаги:
Другая очень важная часть тестирования – это испытание приолжения с помощью Комплекта сертификации приложений для Windows (Windows App Certification Kit, WACK). Данный инструмент подвергает ваше приложение всем автоматизированным тестам, которые оно проходит после отправки в Магазин Windows, таким образом, позволяя вам исправить найденные проблемы. Прохождение тестов WACK не гарантирует, что ваше приложение будет принято, но, определенно, сохраняет вам много времени на ожидание результатов отправки и избавляет от необходимости повторно отправлять приложение снова и снова. Вам следует, на самом деле, запускать WACK практически ежедневно в процессе разработки. Вам не обязательно исправлять всё, что он обнаружит, сразу же, но текущие данные будут весьма полезными.
Для того, чтобы узнать подробности об этом инструменте и о работе с ним, смотрите материал "Тестирование приложения с помощью комплекта сертификации приложений для Windows" (http://msdn.microsoft.com/library/windows/apps/hh694081.aspx) и "Тестирование приложений с помощью комплекта сертификации приложений для Windows" (http://msdn.microsoft.com/library/windows/apps/jj657973.aspx).
Совет. Если вы обнаружили, что WACK не отображает приложения для тестирования, попытайтесь деинсталлировать примеры SDK, которые вы могли запускать из Visual Studio. Такое ощущение, что иногда этот инструмент испытывает перегрузки.
Когда вы готовы к отправке приложения в Магазин Windows, вы можете использовать меню Visual Studio Магазин (Store). Команда Создать пакеты приложения (Create App Package) позволит вам создать пакет, готовый для отправки в Магазин Windows (и для запуска в WACK). Команда Отправить пакеты приложения (Upload App Package) перенаправит вас в Информационную панель Магазина Windows для того, чтобы завершить этот процесс. И, если вам интересно, максимальный размер приложения для загрузки – 2 Гб (смотрите материал "Сборка пакета приложения" (http://msdn.microsoft.com/library/windows/apps/hh694075.aspx).
В процессе отправки приложения у вас запросят все рекламные материалы и сведения, которые мы обсудили выше, а так же URI технической поддержки и страницы с соглашением о конфиденциальности. Так же вы можете выбрать целевые рынки, установить цены, ввести подробности по покупкам из приложения, задать время действия пробного периода, задать дату выпуска, и предоставить примечания для тестировщиков Магазина Windows. (Обзор этого процесса представлен в материале "Контрольный список для подачи приложения" (http://msdn.microsoft.com/library/windows/apps/hh694062.aspx). Последнее очень важно, если что-либо может быть важным для реально существующего человека, который будет тестировать ваше приложение, например, учетные данные для тестовой учетной записи. И, да, реальные люди будут смотреть на ваше приложение (и читать ваши примечания, поэтому будьте вежливы)! Автоматизированные тесты могут сделать довольно много, но в конце кто-то должен запустить приложение и взглянуть на всё своими глазами.
Если вы проделали большую работу для того, чтобы обеспечить доступность приложения, кстати, есть специальное место для того, чтобы это указать. Смотрите материал "Объявление о специальных возможностях вашего приложения в Магазине Windows" (http://msdn.microsoft.com/library/windows/apps/Hh700322.aspx).
Как только ваше приложение пройдёт процесс тестирования, оно будет либо принято, либо отвергнуто. Принятие – это не проблема – это то, чего вы и ожидаете. А если ваше приложение не принято, с другой стороны, из Магазина Windows вам сообщать, почему, перечислив нарушения правил сертификации приложений для Windows 8. На самом деле, эти правила содержат причины, по которым приложение может быть не принято, поэтому каждый отказ в публикации должен содержать конкретное требование, которое не было удовлетворено. Магазин Windows так же предоставляет некоторые сведения об ошибках, о том, где именно приложение аварийно завершило работу (нарушение пункта требований 1.2.)
По большому счету, большая часть правил достаточно проста, поэтому если вы их нарушили, довольно понятно, почему это так. Некоторые, однако, выглядят запутаннее и субъективнее, и в первые дни существования предварительного релиза Windows 8 они были просто загадочными. Сейчас, к счастью, составлен обширный список причин того, почему приложение может нарушить эти правила, он содержится в материале "Устранение ошибок сертификации" (http://msdn.microsoft.com/library/windows/apps/hh921583.aspx), многие из этих ошибок пришли из опыта работы с реальными приложениями, отправленными в Магазин Windows. Тестировщики Магазина Windows так же могут предоставлять непосредственные отзывы относительно специфических ошибок, наподобие того, где и когда приложение может аварийно завершиться, что, конечно, принуждает их отказывать в сертификации.
У книг и приложений есть общая черта, когда в момент их выпуска вы находите ошибки, нестыковки, опечатки и сотни других вещей, которые вам хочется исправить. К счастью, обновить приложение легче, чем обновить книгу (даже несмотря на то, что исправить ошибку в приложении часто сложнее, чем исправить опечатку).
Вы можете решить выпустить обновление по многим причинам, помимо исправления очевидных проблем, которые вы увидели сами и реализации возможностей, которых нет в текущей версии. Вам может захотеться ответить на обзоры и вопросы пользователей, добавить больше продуктов для покупки из приложения, или добавить функции для достижения новых возможностей. Для почти всех этих целей, отчеты и данные (http://msdn.microsoft.com/library/windows/apps/jj193602.aspx), поступающие из Магазина Windows могут быть весьма ценными. Вы будете просматривать их как только ваше приложение окажется в Магазине Windows и лучше всего составить план по мониторингу наиболее интересных для вас отчетов.
Некоторые соображения по этому поводу можно найти в материале "Обновление вашего приложения для Магазина Windows" (http://msdn.microsoft.com/library/windows/apps/jj606115.aspx). На самом деле, запланируйте некоторое время в будущем прямо сейчас для того, чтобы проверять эти отчеты, чтобы не забыть об их существовании. И данные отчеты, действительно, это лучший способ связи с реальными пользователями.
Все подобные данные, конечно, попадают в ваши процессы планирования и разработки, в конечно мсчете, приводя вас к моменту загрузки вашего приложения с новыми рекламными материалами и новыми функциями. Когда вы готовы к загрузке нового пакета, не забудьте увеличить номер версии в манифесте, чтобы вы могли это учитывать. (Эти сведения доступны во время выполнения из Windows.ApplicationModel.Package.current.id.version (http://msdn.microsoft.com/library/windows/apps/windows.applicationmodel.packageid.version.aspx) ). Процесс отправки не отличается от отправки любого другого приложения – не важно, как малы изменения, приложение снова пройдёт полный процесс сертификации. По этой причине не планируйте мелких изменений – сделайте каждое из них значительным (исправка одной критической ошибки, безусловно, имеет значение)! Кроме того, знайте, что сертификационные требования могут время от времени изменяться, поэтому, если приложение однажды уже прошло сертификацию, это не означает, что оно снова её пройдёт. Возьмите себе за правило периодически пересматривать требования.
В обновленном приложении будьте готовы выполнить миграцию состояний, которые могут уже присутствовать на компьютере, если они меняются. Об этом вы можете посмотреть в Главе 2 курса "Пользовательский интерфейс приложений для Windows 8, созданных с использованием HTML, CSS и JavaScript", где говорится о разнице между версиями приложений и версиями их состояний; множество версий приложения может использовать ту же самую версию состояния приложения. Однако, если приложение теперь использует новую версию состояния, старая версия должна мигрировать. Помните так же, что вы можете использовать для этого фоновую задачу servicingComplete, об этом говориться в Главе 2. И, наконец, как только вы представили новую версию состояния приложения, перемещаемые данные будут перемещаться между приложениями, работающими с одной и той же версией состояния – вы можете произвести миграцию старых состояний, когда новое приложение запущено, но как только версия будет увеличена, данные больше не будут перемещаться на устройства с более старой версией приложения.
Последнее, что стоит сказать об обновлениях, это то, что хотя новый пакет приложения может быть достаточно велик, существующим пользователям не придется загружать всё. Пакет приложения разбит на блоки размером по 64 Кб, и лишь те блоки, которые изменились между версиями необходимо загрузить для выполнения обновления. С практической точки зрения это означает, что вам не следует беспокоиться при создании критических обновлений к приложениям: они затронут только небольшую часть кода, и существующие пользователи приложения, в итоге, вполне могут загрузить лишь один блок размером в 64 Кб! Для того, чтобы этому помочь, постарайтесь, чтобы в вашем проекте лучше было бы больше файлов маленького размера, нежели несколько больших, и лучше вносить изменения в конце файлов, чем в начале или в середине.
Гэндальф Серый сказал Фродо, Сэму, Мерри и Пиппину в завершении фильма "Властелин колец": "Мой труд завершён. Здесь, на берегу моря, нашему братству приходит конец". И, мои друзья, я был счастлив совершить это путешествие вместе с вами! В этом последнем разделе я хочу рассказать вам об одном техническом вопросе – о связи приложения с вашим веб-сайтом – прежде чем поделюсь некоторыми итоговыми мыслями.
Если у вас есть приложение, то почти наверняка у вас есть сайт, который предоставляет дополнительную информацию и поддержку (пункт 6.3. требований посвящен технической поддержке). Что, если потенциальный покупатель сначала попал на ваш сайт? Очевидно, вы хотели бы предоставить ему простой способ для получения вашего приложения, если он работает на Windows 8.
Для того, чтобы это сделать, вы можете просто предоставить ему ссылку на специальный URI, ведущий в Магазин Windows, начинающийся с ms-windows-store, как описано в материале "Ссылки на приложение" (http://msdn.microsoft.com/library/windows/apps/hh974767.aspx). Вы можете использовать форму ms-windows-store:REVIEW? для создания ссылки, ведущей непосредственно к оценкам и отзывам о вашем приложении. И, кроме того, помните, что вы можете включить ссылку на страницу вашего приложения в Магазине Windows в пакеты с данными, которые вы предоставляете для контракта Общий доступ, об этом можно узнать в Главе 1.
С помощью Internet Explorer, немного метаданных в теге <head>
вашей веб-страницы упростят пользователю получение вашего приложения и даже его запуск после установки приложения. Например:
<meta name="msApplication-ID"
content="ProgrammingWin8-JS-CH17-HereMyAm17"/>
<meta name="msApplication-PackageFamilyName"
content="ProgrammingWin8-JS-CH17-HereMyAm17_5xchamk3agtd6"/>
Здесь два значения content берутся из полей Имя пакета (Package Name) и Имя семейства пакетов (Package Family Name) на закладке Упаковка (Packaging) редактора манифеста. Если у пользователя нет вашего приложения, это упрощает процесс его получения. Если у пользователя уже есть приложение, у него появляется возможность запустить его, в таком случае приложение будет активировано с видом активации protocol.
Для того, чтобы узнать больше, посмотрите материал "Связывание приложений с ресурсами в Интернете" (http://blogs.msdn.com/b/windowsstore_ru/archive/2012/02/29/linking-to-your-apps.aspx) в блоге для разработчиков Магазина Windows и материал "Связывание вашего веб-сайта с вашим приложением для Windows 8" (http://blogs.msdn.com/b/ie/archive/2011/10/20/connect-your-web-site-to-your-windows-8-app.aspx) в блоге Interner Explorer). И, для того, чтобы увидеть рабочий пример, посетите сайт Inrix Traffic (http://www.inrixtraffic.com/), одного из первых партнёров, который реализовал эту функцию.
Еще одна возможность продвижения приложения, которая приходит здесь в голову: OEM-производителя может заинтересовать ваше приложение для предустановки на их устройства. Если это произойдёт – это настоящий подарок! – тогда OEM-производитель предоставит вам некоторые специальные инструкции о том, как подготовить приложение специально для его клиентов.
Само собой разумеется то, что Магазин Windows будет в какой-то момент содержать огромное количество приложений, в итоге, очень важно будет дифференцировать себя, как разработчика, и своё приложение. Опять же, здесь можно много говорить о маркетинге и приобретении известности вашим приложением, так же, как и о реагировании на нужды клиентов. Помимо этого, однако, что делает приложение по-настоящему особенным?
Ранее, задолго до того, как Microsoft стала использовать термин "Приложения для Магазина Windows", мы называли их "tailored apps" ("индивидуальные", "сшитые на заказ", "подогнанные"). Поэкспериментируем с этим старым термином, подумаем о том, что "подгонка" означает в контексте одежды: хорошо сшитая одежда весьма заметна. Она позволяет вам выглядеть по-настооящему хорошо. Она позволяет вам хорошо себя чувствовать. Это именно то, что должен чувствовать пользователь вашего приложения, когда он погружается во взаимодействие с ним. На самом деле, так же, как вы получаете море удовольствия и счастья от процесса разработки, пусть то же самое испытывают и пользователи ваших приложений. Если вы можете принести им радость с помощью вашего приложения, тогда, я думаю, вы добились этой цели!
Другое значение слова "tailored" подразумевает, что те программы, которыми мы здесь занимаемся – это приложения, которые запускаются на полном экране и полностью погружают пользователя в работу с ними, позволяют такому взаимодействию распространяться и на устройство, и на контекст пользователя. Датчики, речь о которых идет в Главе 3 курса "Пользовательский интерфейс приложений для Windows 8, созданных с использованием HTML, CSS и JavaScript", дают вам возможность знать о взаимоотношениях устройства с физическим миром, который является продолжением пользователя, который держит устройство. Спросите тогда: "Что я могу делать с подобной информацией? Как может вести себя приложение, когда у него есть более глубокое понимание того, где находится пользователь, как он перемещается? Если что-то большее, что может сделать приложение, чем спросить: "Рады ли вы, что взяли меня с собой?".
Для того, чтобы выделить ваше приложение, подумайте о том. как пользователь может использовать устройства разных форм-факторов в разных ситуациях, и выглядит ли приложение по-разному в разных ситуациях. Подобный вид персонализации подразумевает то, что приложение содержит наиболее подходящие возможности или содержимое для наиболее вероятных или подходящих вариантов использования. В соответствии с нижеприведенным рисунком, мне нравится думать о том, что одно и то же приложение может существовать на разных устройствах, и что у пользователя имеется более сильная связь именно с приложением, а не с устройством, на котором оно работает.
Чтение журналов, пометка интересных рецептов (Read magazines, mark recipes of interest)
Планирование меню с отмеченными рецептами, составление списка покупок (Plan menus with marked recipes, make shopping lists)
Просмотр списка покупок, поиск магазинов с лучшими ценами (И, да, здесь у Microsoft есть история с телефонами…) (See shopping lists, locate stores with best prices (And yes, Microsoft will eventually have a story with the phones here…))
Подготовка дневного рациона в соответствии с планом меню (а это – планшет, который можно мыть в посудомоечной машине!) (Prepare the day’s meals according to menu plan (this is a dishwasher-safe tablet too!))
Варианты использования приложения для планирования рациона
Приложение и лежащие в его основе возможности действуют последовательно, во всём диапазоне возможных ситуаций работы с приложением, когда устройство – это лишь транспортное средство. Чем больше ваше приложение соответствует этому и поддерживает это (очевидно, перемещаемые данные здесь очень важны), тем больше, мне кажется, приложение отличается в лучшую сторону от других приложений, которые, конечно, работают в новом окружении Windows, но предлагают те же модели использования, которые существуют уже многие годы
Так как же приложению стать звездой? Давайте будем честными. Вы в этой игре ради имени и славы, верно? И ради больших денег, которые с ними приходят? Какое приложение может дать вам всё это?
Итак, вот последний абзац (если не считать сводки в конце лекции). Я не могу, на самом деле, дать вам кучу конкретных идей (иначе я писал бы эти программы вместо того, чтобы писать книги, но кто-то должен делать и эту работу…). Но задумайтесь над этим: что способствует появлению рок-звезды в музыкальной индустрии? Обычно это не философская глубина лирики или виртуозное исполнение. Это – шоу, личность, ценность зрелищных мероприятий, полных счастья. Это – радость, которая превращает обычных людей в безумных фанатов, которые жаждут быть вашими горячими сторонниками. На самом деле, впечатления – это то, что позволяет людям сбежать из их повседневной реальности и стать частью чего-то большего на какое-то время, или даже частью фантазии. И, как в случае с великой музыкой или великими фильмами, позитивные впечатления от приложения, это то, что людям хочется повторять снова и снова, а не просто ставить галочку, как другие "был там, сделал это". Хотя это, конечно, вопросы времени и счастливой случайности, но все рок-звезды, вместе с великими спортсменами, фильмами, получившими Оскар, вроде "Властелина колец", и так далее, стремились, прежде всего, лишь к одному: к совершенству. Посвятите себя этому. Посвятите себя совершенству во всём, что вы делаете – не только в разработке приложений, но и во всех сферах собственной жизни. Подобное стремление, несомненно, принесет вам множество потрясающих результатов!
Как я упоминал во введении к этой лекции, примерно 60% пользователей используют, в некотором объеме, функции специальных возможностей. Иногда – это потому что эти люди имеют реальные физические ограничения, иногда – лишь потому, что им это нравится, и иногда – лишь для того, чтобы облегчить использование устройства в определенных условиях.
Во многих странах доступность применения чего-либо людьми с ограниченными физическими способностями (в нашем случае речь идет о специальных возможностях программного обеспечения) – это требование законодательства, в итоге, это необходимо, если вы планируете сделать приложение доступным для подобных регионов. Коротко говоря, поддержка специальных возможностей – это то, что вашему приложению следует реализовать, и оно должно делать это хорошо. К счастью, это не такая уж и сложная задача, как может показаться. (Посмотрите материалы "Создание специального приложения" (http://msdn.microsoft.com/library/windows/apps/hh452681.aspx) и "Введение в использование специальных возможностей в Веб" (http://msdn.microsoft.com/library/windows/desktop/gg671915.aspx). Второй материал посвящен веб-приложениям, но вполне применим и для приложений для Магазина Windows . Кроме того, посмотрите материалы "Руководство и контрольный список для специальных возможностей" (http://msdn.microsoft.com/library/windows/apps/hh700325.aspx), "Методики, которых следует избегать при создании приложений со специальными возможностями" (http://msdn.microsoft.com/ru-ru/library/windows/apps/hh452715.aspx) и "Реализация специальных возможностей для определенных типов содержимого" (http://msdn.microsoft.com/library/windows/apps/hh700326.aspx)).
Может показаться, для реализации специальных возможностей понадобится много работы, так как разработчики сравнительно мало знакомы с тем, что это означает. Чтобы это исправить, потратьте несколько минут на то, чтобы получить непосредственный опыт работы со специальными возможностями. Но, прежде чем вы сделаете что-то еще:
Пройдите в раздел Параметры ПК>Синхронизация параметров (PC Settings>Sync Your Settings) и выключите опции Персонализация рабочего стола (Desktop Personalization) и Специальные возможности (Ease of Access). В противном случае, эффекты, с которыми вы экспериментируете будут перемещены на другие устройства, которые могут у вас быть. Я узнал это на собственном опыте, когда я экспериментировал с настройками контрастности на ноутбуке, после чего экран игры, в которую хотел поиграть мой сын на планшете, практически полностью почернел! Очевидно, то приложение не поддерживало схему высокой контрастности, но мне понадобилось некоторое время для того, чтобы во всём разобраться!
Теперь, когда мы позаботились об этих деталях, попробуйте следующее:
Благодаря полученному опыту, я надеюсь, вы получили некоторое понимание того, что означают специальные возможности. Проще говоря, они предназначены для ключевых сценариев поддержки доступности приложений: это работа с экранным диктором, ввод данных только с помощью мыши или только с помощью клавиатуры, схемы с высокой контрастностью и масштабирование разрешения.
Две последних темы раскрыты в Главе 6 курса "Введение в разработку приложений для Windows 8 с использованием HTML, CSS и JavaScript", там рассказано, как работать с различными масштабами разрешения, как обрабатывать различные размеры экрана (что может произойти в результате масштабирования разрешения) и как предоставлять растровые изображения для различных масштабов разрешения для обеспечения их наилучшего вида. В качестве краткого руководства вы так же можете воспользоваться примером "Масштабирование в соответствии с DPI" (http://code.msdn.microsoft.com/windowsapps/Scaling-sample-cf072f4f).
Особенности ввода так же обсуждались в Главе 3 курса "Пользовательский интерфейс приложений для Windows 8, созданных с использованием HTML, CSS и JavaScript". Напоминаю вам снова, что политика сертификации приложения (раздел 3.5.) требует, чтобы приложения поддерживали все формы ввода. Обычно это не проблема в случае с мышью и сенсорным экраном. Настоящая работа начинается тогда, когда нужно убедиться в том, что вашим приложением можно пользоваться, применяя лишь клавиатуру. Обратитесь за подробностями к материалу "Реализация специальных возможностей клавиатуры" (http://msdn.microsoft.com/library/windows/apps/hh700327.aspx). Тестирование приложения с использованием Экранного диктора так же позволяет обнаружить, уделили ли вы достаточно внимания навигации с помощью клавиатуры, так как неважно, какие подписаны ваши элементы управления, если пользователь даже не может установить на них фокус ввода!
Так же полезно упомянуть, что включение скрытых подписей в видео может помочь людям с ослабленным слухом. Выполнение этого, однако, больше относится к видеоданным, или может быть реализовано с помощью наложения текстового элемента на элемент управления, выводящий видео. Смотрите материал "HTML5 и специальные возможности" (http://msdn.microsoft.com/en-us/magazine/hh204741.aspx) в MSDN Magazine для того, чтобы больше узнать о специальных возможностях видео.
Посмотрим теперь, как мы можем поддержать возможности работы с Экранным диктором и высококонтрастные схемы.
Windows SDK включает в себя два инструмента, которые могут помочь вам проверить вашу реализацию специальных возможностей. Первое называется Inspect, это средство для автоматической проверки пользовательского интерфейса, которое проверяет данные специальных возможностей, которые вы предоставляете экранному диктору и даёт вам знать, что вы пропустили. Второе называется AccChecker, которое выполняет серию проверок всего приложения. Вы можете найти эти инструменты в папке установки Windows SDK, обычно в c:\Program Files (x86)\Windows Kits\8.0\bin\x86. Кроме того, вас могут заинтересовать инструменты Accessible Event Watcher и UI Automation Verify. Подробности об их использовании можно найти в материалах "Инструменты тестирования" (http://msdn.microsoft.com/library/windows/desktop/dd373661.aspx) и "Проверка специальных возможностей приложения" (http://msdn.microsoft.com/library/windows/apps/hh452726.aspx). Конечно, для наиболее полного тестирования, найдите несколько пользователей, которые регулярно работают с технологиями специальных возможностей, настройте им лицензию разработчика (так вы сможете установить у них пакет приложения) и передайте им приложение для тестирования.
Подготавливая ваше приложение к возможности навигации с помощью клавиатуры, не используйте атрибуты tabindex для элементов, которые в них не нуждаются, полагая, что подобный поможет Экранному диктору работать с неинтерактивными элементами. Это, на самом деле, не так. Экранный диктор имеет собственные клавиатурные команды (CapsLock+клавиши-стрелки) и собственные режимы навигации, которые позволяют ему прочесть для пользователя всё, что находится на экране, независимо от tabindex. По этим причинам, установка атрибута tabindex для статических элементов вредит удобности работы с Экранным диктором. Вам следует устанавливать это свойство только для интерактивных элементов. Другими словами, нужно понимать, что работа с приложением с использованием клавиатуры и работа с Экранным диктором – это разные вещи, и размышляйте о tabindex только в контексте навигации с помощью клавиатуры.
Средства для чтения с экрана, наподобие встроенного Экранного диктора, могут работать только тогда, когда приложения предоставляют некоторые данные, которые сообщают средству чтения с экрана об элементах управления в пользовательском интерфейсе. В случае с приложениями для Магазина Windows , написанных на HTML, CSS и JavaScript, это реализуется с помощью атрибутов aria-* элементов пользовательского интерфейса.
Совет. Если вам нужны отдельные возможности по переводу текста в речь, то, например, API Microsoft Translator (http://www.microsofttranslator.com/dev/), включает в себя метод Speak, доступный посредством интерфейсов AJAX, SOAP, и HTTP, генерирующее WAV или MP3-поток для текста на заданном языке. Существуют и другие веб-сервисы для этой цели, и библиотеки сторонних разработчиков.
ARIA – это сокращение для Accessible Rich Internet Applications, стандарта, который выражен в спецификациях WAI-ARIA (http://www.w3.org/TR/wai-aria/). WIA расшифровывается как W3C Web Accessibility Initiative (http://www.w3.org/WAI/intro/aria.php). Два других W3C-документу, связанные с этой темой, это WAI-ARIA Primer (http://www.w3.org/TR/wai-aria-primer/) и WAI-ARIA Authoring Practices (http://www.w3.org/TR/wai-aria-practices/).
Это сводится к тому, что вспомогательные технологи, наподобие Экранного диктора, могут автоматически получать из определенных элементов то, что им нужно, наподобие заголовков, абзацев, атрибута title, элементов label, связанных с элементом, который может принимать фокус ввода (с использованием атрибута надписи for), текста кнопок, элементов ввода данных, атрибута таблиц caption, и атрибута alt элементов img. Атрибуты играют здесь немалую роль.
Для всего остального, такого, как элементы ) в Центре разработчиков Windows. Еще один хороший материал, это "Предоставление основных сведений об элементах пользовательского интерфейса" (http://msdn.microsoft.com/library/windows/apps/Hh700323.aspx), который содержит примеры использования основных атрибутов aria-*. На данной странице есть особое замечание по поводу элемента canvas. Так как этот элемент, по сути, представляет собой набор пикселей, он обычно не имеет содержмого, доступного средствам чтения с экрана, даже если выводимые им данные выглядят как текст. Таким образом, нужно приложить особые усилия для того, чтобы придать этому элементу соответствующие атрибуты, как делается с другими пользовательскими элементами управления (сновап посмотрите материал "HTML5 и специальные возможности" (http://msdn.microsoft.com/en-us/magazine/hh204741.aspx), в частности, раздел, посвященный canvas).
Все элементы управления WinJS полностью снабжены атрибутами ARIA, они так же работают с технологиями специальных возможносей, поэтому используя их, вы получаете реализацию этих возможностей по умолчанию (Исключение – это элемент управления SematicZoom, который обычно не имеет атрибута aria-label, так как является контейнером для других элементов управления, которые должны иметь собственные подписи). Таким образом, вам всё еще нужно соовтетствующим образом поработать с другими элементами, в том числе и HTML-элементами управления наподобие progress. Вот сводка по основным атрибутам aria- *:
aria-label Напрямую предоставляет текст для средств чтения с экрана.
aria-labelledby (Обратите внимание на две буквы l) Задает идентификатор другого элемента, который содержит подпись для элемента. Спецификация сообщает, что атрибут aria-labelledby следует использовать вместо aria-label, если необходимый текст уже выведен на экран.
aria-describedby Похож на aria-labelledby, идентифицирует элемент, который содержит более полное описание, а не только текст подписи. Экранный диктор читает этот текст, если пользователь нажимает комбинацию клавиш Win+Alt+F для элемента, имеющего этот атрибут. Это хороший атрибут для использования с элементом canvas, который содержит текст, выведенный в виде графики: если вы так же сохраните этот текст в другом элементе, связанном с данным атрибутом, даже в скрытом, у пользователя будет возможность услышать прочитанное экранным диктором содержимое этого элемента.
aria-valuemin, aria-valuemax, и aria-valuenow У элементов div, роль которых в предоставлении доступа к полосам прокрутки, индикаторам выполнения задач, кнопкам-счетчикам, эти атрибуты показывают значения внутри элемента управления. aria-valuetext так же может предоставлять текст, который связан со значением aria-valuenow.
aria-selected, aria-checked, aria-disabled и aria-hidden Указывают на состояние элемента.
aria-live Нужен для содержимого, которое динамически изменяется, такого, как список основных сведений, чат, RSS-канал, загрузка фрагментов и так далее.
В Главе 4 курса "Введение в разработку приложений для Windows 8 с использованием HTML, CSS и JavaScript" мы рассматривали специальный синтаксис, который применяется для привязки данных к атрибутам целевых элементов, которые не связаны с JavaScript-свойствами. Атрибуты aria-* представляют собой примеры подобных атрибутов, со своими именами, которые пишутся через дефис, для работы с которыми мы используем this[ ] а так же специальные WinJS-инициализаторы в data-win-bind:
<div data-win-bind="this['aria-label']: title WinJS.Binding.setAttribute"></div> <div data-win-bind="this['aria-label']: title WinJS.Binding.setAttributeOneTime"></div>
Более вероятно, однако, что вы будете предоставлять локализованные ARIA-подписи в ресурсах приложения, и для них используется другой декларативный синтаксис, который мы увидим позже, в разделе "Готовность к мировому рынку и локализация".
Для того чтобы увидеть, как Экранный диктор работает с различными атрибутами aria-* лучше всего обратиться к уникальному примеру работы с ARIA (http://code.msdn.microsoft.com/windowsapps/Aria-sample-f3cf5323) в Windows SDK. Одна из его уникальных характеристик заключается в том, что он не выглядит как пример SDK, как вы можете видеть на рис 16.1. Это сделано преднамеренно, для показа содержимого типичного приложения, без использования обычных элементов оформления, используемых в примерах. В данном случае пример имитирует простое чат-приложение с чем-то вроде списка основных сведений в левой части окна.
(рис 16.1) Главное окно примера работы с ARIA
Когда вы запустите этот пример, на забудьте включить Экранный диктор для того, чтобы слышать то, что он говорит. (Рекомендую делать это в имитаторе Visual Studio, так как в таком случае Экранный диктор будет работать лишь в данном сеансе работы, а не для всего вашего компьютера!). Вы обнаружите, что он точно отражает то, что происходит на экране, в особенности то, как вы переходите между элементами управления с помощью Tab или Shift+Tab, нажимаете клавиши Enter или Пробел для выбора элементов и вводите текст в чат. Опять же, выключите монитор, закройте глаза, притворитесь незрячим или предложите своему пятилетнему ребенку стать позади вас и закрыть вам глаза ладошками для того, чтобы получить полные ощущения от работы с примером.
Нажатие Enter на элементе в списке, который расположен слева, обновляет контактные данные, которые находятся в нём. Выбор одного из этих контактов и нажатие Enter откроет другую страницу с таблицей, очевидно, не содержащую реальных данных, но она демонстрирует применение атрибутов aria-*. Страница, показанная на рис 16.2, так же предоставляет возможность испытать навигацию посредством клавиатуры и Экранного диктора.
(рис 16.2) Дополнительная страница примера работы с ARIA (слегка обрезано)
За исключением небольшого кода в pages/chat/chat.js, предназначенного для работы с окном чата, по-настоящему интересная часть этого примера целиком содержтся в разметке, в частности, в файлах pages/chat/chat.html (главная страница) и pages/table/ table.html (дополнительная страница). В коде первой мы видим aria-label у большинства из элементов управления (с текстом, который вы можете слышать, перемещаясь по странице), и гораздо больший набор атрибутов для элемента div, который выводит окно чата около нижней части:
<div class="chatpage fragment">
<header aria-label="Header content" role="banner">
<button class="win-backbutton" aria-label="Back" disabled=""></button>
<h1 class="titlearea win-type-ellipsis">
<span class="pagetitle">Aria Sample</span>
</h1>
</header>
<section aria-label="Main content" role="main">
<div class="chat">
<div class="groupslist" aria-label="List of groups" data-win-control="WinJS.UI.ListView"
data-win-options="{ selectionMode: 'none'}"></div>
<div class="contactslist" aria-label="List of contacts" data-win-control="WinJS.UI.ListView"
data-win-options="{ selectionMode: 'none' }"></div>
<div class="chatTextContainer">
<div class="chatTextEchoContainer" aria-label="Chat text area"
aria-live="assertive" aria-multiline="true" aria-readonly="true" aria-relevant="additions" role="log"
tabindex="0"></div>
<input class="chatTextInput" accesskey="i" aria-label="Chat input area" type="text"
value="Type here..."/>
</div>
</div>
</section>
</div>
Этот div, с классом chatTextEchoContainer, обновляется во время выполнения программы и включает в себя при этом дочерние div-элементы для каждой текстовой записи. По этой причине у него есть атрибут aria-live, значения которого описываются как "уровень вежливости" в спецификациях W3C. Значение assertive сообщает "применить изменения сразу же", что подходит для чата, но этим следует пользоваться осторожно. Другое значение, polite (значение по умолчанию для элементов role="log"), указывает на более низкий приоритет, то есть Экранный диктор не будет прерывать текущую задачу по озвучиванию. Атрибут aria-relevant="additions" относится к этому, показывая, какие изменения относятся к динамически изменяющейся (live) области. Его возможные значения: additions, removals, text, и all. В случае со значением additions, если мы добавим в окно чата изображение для него с атрибутом alt, оно будет озвучено. Если же мы установим его в значение text, озвучиваться будет лишь содержимое текстовых элементов.
Атрибут aria-multiline указывает на то, что окно чата – это многострочный текстовой элемент, то есть, нажатие на клавишу Enter воспринимается как ввод текстового символа перевода строки, а не как команда для отправки сообщения (как в случае однострочного текстового элемента). Атрибут aria-readonly показывает, что содержимое элемента управления нельзя править для того, чтобы отличать такие элементы от тех, которые маркированы атрибутом aria-disabled.
Если вы поэкспериментируете с примером, вы заметите, что когда вы активируете окно чата, Экранный диктор читает всё его содержимое. Когда вы вводите строку в однострочный элемент управления, с другой стороны, Экранный диктор читает лишь те символы, которые были добавлены. Это происходит потому, что для атрибута aria-atomic (он не представлен в разметке) значение по умолчанию – false. При использовании с элементом, маркированным как aria-live это сообщает средству чтения с экрана, что нужно читать только изменившийся узел в данном элементе. Если вы установите aria-atomic в true, изменения любого дочернего элемента будут считаться элементами всего элемента, в итоге, всё его содержимое будет прочитано. Это можно использовать на разных уровнях, заметьте, таким образом, если вы добавляете дочерний элемент, который является атомарный, а потом добавляете внучатый элемент в него, лишь содержимое этого атомарного дочернего элемента будет прочитано, если родительский элемент не является атомарным.
Что касается разметки на странице pages/table/table.html, она дает нам пример использования aria-describedby. Вот соответствующий раздел этой разметки, содержимое таблицы опущено:
<div class="detail">
<h2 id="title" role="heading" aria-level="2">Sample table</h2>
<p id="subtitle" role="note">This table shows sample data.</p>
<p class="generaltext">...</p>
<table class="tabledetail" aria-describedby="subtitle"
aria-labelledby="title" border="1">
<!-- Содержимое опущено -->
</table>
</div>
Когда вы устанавливаете на таблицу фокус ввода в исполняющемся примере (вы должны использовать для этого мышь, если только вы не добавили tabindex к таблице), вы сначала услышите "Sample table" в соответствии с атрибутом aria-labelledby. Затем нажмите Win+Alt+F, и вы услышите текст "Item described by…", за которым будет следовать текст, заданный aria-describedby.
Отметим, наконец, что очень важно, чтобы элементы title и subtitle так же имели атрибуты, имеющие отношение к aria-, такие, как role. В противном случае aria-labelledby и aria-describedby работать не будут.
Работа с моделями высокой контрастности, это, преимущественно, принятие изменения цветовой темы Windows и проверка того, что графические элементы вашего приложения соответствуют требованиям высокой контрастности. С технической точки зрения, высокая контрастность, как её определяет W3C это минимальный коэффициент контрастности 4.5:1. Полное пояснение того, как измерить этот коэффициент, расположено по адресу (http://www.w3.org/TR/WCAG20-TECHS/G18.html). Анализатор контрастности (http://www.paciellogroup.com/node/18?q=node/20) от Paciello Group так же позволяет проверить изображения (некоторые из моих в приложении "Here My Am!" тест не прошли). Обратите внимание, однако, что создание высококонтрастной графики не требуется для содержимого, не несущего информацию, такого, как логотипы и декоративные изображения. В то же время, полноцветная графика может выглядеть не на своём месте в высококонтрастном режиме, поэтому не забудьте оценить общее впечатление от программы при работе с ней пользователей в подобных условиях.
Приложение может поддерживать высокую контрастность с помощью четырех подходов. Первый заключается в том, чтобы использовать встроеные элементы управления (и HTML и WinJS) и позволить системе делать свою работу! Для того, чтобы увидеть, что произойдёт, запустите несколько примеров использования элементов управления, например "Основные элементы управления HTML" (http://code.msdn.microsoft.com/windowsapps/Common-HTML-controls-and-09a72a24) и "HTML-Элемент управления Rating" (http://code.msdn.microsoft.com/windowsapps/Rating-control-sample-4666c750) и пеереключайтесь между разными темами высокой контрастности в разделе Персонализации Панели управления..
Конечно, почти всегда у приложения есть некоторые собственные элементы управления, такие, как div-элементы с пользовательскими цветовыми схемами, заданными в CSS. Вам следует убедиться, есть ли у вас подходящие правила стилей для настроек высокой контрастности, для которых присутствует медиа-характеристика ) для медиа-запросов, которая похожа на -ms-view-state, которая рассматривается в Главе 6 курса "Введение в разработку приложений для Windows 8 с использованием HTML, CSS и JavaScript". Эта характеристика может принимать значения active (для применения данного правила ко всем темам с высокой контрастностью), black-on-white (тема с белым фоном), white-on-black (тема с черным фоном), и none. Очевидно, none означает, что вы не используете -ms-high-contrast для группировки любых правил; active так же подразумевает, что вы используете -ms-high-contrast без значения. В следующем разделе мы рассмотрим их более подробно.
Как и в случае с состояниями просмотра, вы можете использовать прослушиватели медиа-запросов и ) который указывает на то, разрешено ли переопределять обычные свойства CSS элемента для целей высокой контрастности. Значение по умолчанию, auto, это позволяет; значение none предотвращает такое поведение. Опять же, скоро мы это увидим.
Далее, WinRT представляет текущие установки контрастности посредством класса ). У него есть два свойства: ), код здесь весьма прост:
var accessibilitySettings = new Windows.UI.ViewManagement.AccessibilitySettings();
id("highContrast").innerHTML = accessibilitySettings.highContrast;
id("highContrastScheme").innerHTML = accessibilitySettings.highContrast ?
accessibilitySettings.highContrastScheme : "undefined";
WinRT так же предоставляет подробную информацию о цвете посредством метода ). (Обратите внимание на странный регистр символов в uIElementColor, артефакт результатов проекции WinRT-имен в JavaScript.). Он возвращает объект ) для элемента, идентифицируемого с помощью ). Сценарий 1 примера о работе с контрастностью показывает все эти возможности на примере поучительного, но довольно скучного кода, который я здесь дублировать не буду.
Объект AccessibilitySettings, кроме того, поддерживает одно событие, highcontrastchanged, которое позволяет вам узнать, когда включена или выключена высокая контрастность. Его eventArgs.target является объектом AccessbilitySettings, который содержит свежие данные. Вы можете использовать это событие для вызова любого необходимого программного обновления, которое нужно выполнить в вашем пользовательском интерфейсе, например, для перерисовывания элемента canvas с использованием высококонтрастных цветов, если вы не используете для этой цели прослушиватель медиа-запроса.
Наконец, и для растровых и для векторных изображений применяется соглашение об именовании фйлов, которое используют вместе с суффиксами .scale-100, .scale-140, и .scale-180 для обозначения плтности пикселей. Суффиксы для контрастности – это: .contrast-standard, .contrast-high, .contrast-black (чёрное на белом), и .contrast-white (белое на черном). Мы увидим всё это в действии в разделе "Ресурсы для схем высокой контрастности" ниже, и увидим, как комбинировать суффиксы масштаба и высокой контрастности в разделе "Масштаб + контраст = Квалификаторы ресурсов"
Пример "CSS-стилизация для режима высокой контрастности" (http://code.msdn.microsoft.com/windowsapps/High-Contrast-b36079d8) предоставляет рассмотрение ценного подхода по работе с режимами высокой контрастности, где используются медиа-запросы и файлы изображений. Как вы можете ожидать, основное количество этих возможностей показано в виде декларативных CSS-объявлений и ресурсов приложения. Лишь один сценарий содержит JavaScript-код!
Сценарий 1 показывар разрицу между элементами, которые учитывают использование схемы высокой контрастности и элементами, коорые этого не делают. При использовании обычной цветовой схемы, все три кнопки выглядят так, как показано ниже, где первые две – это элементы div, а третья – это настоящий элемент button.
Когда включается высокая контрастность (Левый Shift+Alt + Print Screen очень удобно переключают режимы при работе с этим примером), они выглядят так:
Первый элемент управления, не учитывающий использование схемы высокой контрастности, всё еще использует белый цвет для границы, которые, конечно, исчезают на белом фоне. Вторая кнопка, с другой стороны, имеет стили, которые используют цвета, заданные системой, связанные с медиа-запросом для режима высокой контрастности, в итоге кнопка нормально работает при использовании любой темы (css/scenario1.css):
@media (-ms-high-contrast) {
.s1-hc {
background-color: ButtonFace;
color: ButtonText;
border: 1px solid ButtonText;
}
/* ... */
}
Совет. Если решили полностью положиться на системные цвета, и в CSS, и в SVG, тогда вы можете вовсе не использовать медиа-запросы или различные SVG-файлы, так как их цвета будут настроены для темы с высокой контрастностью автоматически. Смотрите материал "Системные цвета" (http://msdn.microsoft.com/library/ie/aa358804.aspx). Так же вы можете использовать значение current-Color в SVG для свойств fill, stroke, stop-color, flood-color, и lighting-color для отражения параметров контрастности.
Сценарий 2 показывает похожие эффекты с кнопками, которые используют SVG-изображения для фона. При обычных установках эти кнопки выглядят так:
После включения схемы высокой контрастности они выглядят так:
Всё, что здесь происходить, это использование медиа-запроса для использования, когда это необходимо, высококонтрастного фонового изображения для кнопки:
.s2-button-hc-bg-svg {
background-image: url(../button-not-aware.svg);
background-size: 100% 100%;
width: 200px;
height: 200px;
}
@media (-ms-high-contrast) {
.s2-button-hc-bg-svg {
background-image: url(../button.contrast-high.svg);
background-repeat: no-repeat;
background-size: cover;
}
}
Если вы просмотрите файл ), который будет автоматически подстроен под параметры высокой контрастности).
Что происходит с первой и со второй кнопками? Если вы посмотрите в CSS (css/scenario2.css), вы увидите, что единственное различие заключается в том, что класс стиля для первой кнопки, ), включение высокой контрастности переопределяет большинство цветовых стилей, как и background-image, в последнем случае просту удаляя это изображение. Поэтому первая кнопка отображается пустой. Вторая кнопка имеет правило, определяющее background-image в медиа-запросе, в итоге, фоновое изображение выводится.
Это приводит нас к цели использования стиля -ms-high-contrast-adjust. По умолчанию он установлен в значение auto, позволяя переопределять CSS-свойства. Если мы установим его в значение none в правиле стиля, мы предохраним эти стили от переопределения или настройки. Таким образом, если вы добавите -ms-high-contrast-adjust: none; к правилу .s2-button в css/scenario2.css, вы увидите, что первая и вторая кнопка ведут себя одинаково. Вы можете видеть это изменение в копии примера, в дополнительных материалах к лекции.
Переходим к Сценарию 3, он, в обычном режиме, рисует логотип Internet Explorer в элементе canvas в цвете (левое изображение ниже), в то время как в модели высокой контрастности он рисует логотип в черно-белом варианте (правое изображение):
В данном случае параметры высокой контрастности берутся в JavaScript (js/scenario3.js) с использованием прослушивателя медиа-запроса; CSS здесь не используется (этот код упрощен, для большей понятности, в реальном примере так же производится обнаружение схемы высокой контрастности при запуске приложения):
var fillStyleOuterColor = "rgb(9, 126, 196)";
var fillStyleInnerColor = "rgb(255, 255, 255)";
var mql = matchMedia("(-ms-high-contrast)");
mql.addListener(updateColorValues);
function updateColorValues(listener) {
if (listener.matches) { fillStyleOuterColor = "ButtonText"; fillStyleInnerColor = "ButtonFace";
draw();
}
else {
fillStyleOuterColor = "rgb(9, 126, 196)";
fillStyleInnerColor = "rgb(255, 255, 255)";
draw();
}
Обратите внимание на то, что событие AccessibilitySettings.onhighcontrastchanged можно использовать вместо прослушивателя медиа-запроса.
Элемент canvas – это лучший выбор? В данный момент в приложении "Here My Am!" я использовал изображения для вывода сообщений в элементы img, когда фотография или карта были недоступны. Учитывая нужды работы со схемами высокой контрастности и локализованных вариантов этих изображений, проще взять локализованный строковой ресурс, как мы рассмотрим ниже, и просто создать изображение "на лету" с помощью элемента canvas. Это устраняет необходимость иметь множество различных файлов изображений и уменьшает размер пакета приложения, и, кроме того, полностью соответствует нуждам обеспечения доступности приложения и локализации. Версия "Here My Am!" для этой лекции теперь работает именно так.
В предыдущем разделе, в примере CSS-стилизация для режима высокой контрастности" (http://code.msdn.microsoft.com/windowsapps/High-Contrast-b36079d8) мы столкнулись с соглашениями об именовании файлов, которые загрузчик ресурсов Windows использует для схем высокой контрастности: button.contrast-high.svg, например. Сценарий 4 этого примера показывает, как разрешение таких имен может происходить автоматически. В проекте имеется файл, названный button.svg, вместе с еще одним, который называется button.contrast-high.svg, и с элементом img, который объявлен в html/scenario4.html:
<img src="../button.svg" />
Если система исполняется с нормальными параметрами контрастности, загрузчик ресурсов разрешает это URI в button.svg. (Конструкция ../ используется потому что страница сценария находится на один уровень ниже папки HTML). Когда применены настройки высокой контрастности, загрузчик ищет то же имя файла, но с .contrast-high, вставленным перед расширением.
Примечание. Если вы применяете пользовтельские значки панели приложения (как обсуждалось в Главе 1 курса "Пользовательский интерфейс приложений для Windows 8, созданных с использованием HTML, CSS и JavaScript", не забудьте включить в состав изображений высококонтрастные варианты исходных изображений с использованием данной схемы именования.
Если вы хотите иметь больше параллельных имен файлов, вы так же можете назвать файлы для нормальных настроек контрастности, включив в их имя .contrast-standard, как, например button.contrast-standard.svg. Если вы сделаете это в проекте примера, оставив HTML в том виде, в котором он есть, вы не увидите разницы в выводе данных. В то же время, учитывая особенности поведения системы при работе с контрастностью, рекомендовано использовать .contrast-standard если вы так же поддерживаете варианты .contrast-white и .contrast-black.
Как упомянуто выше, эти варианты применяются автоматически для тем "чёрное на белом" (белый фон) и "белое на черном" (черный фон), соответственно. Для того, чтобы это увидеть, скопируйте файл button.contrast-high.svg, назовите его button.contrast-white.svg, и затем сделайте еще одну копию с именем button.contrast-black.svg. В этой второй копии измените цвета градиента в блоке CDATA, заменив black на ButtonFace. Когда затем вы переключитесь на высококонтрастную тему с черным фоном, вы увидите кнопку в стиле "белое на черном", как это и должно быть.
Все эти изменения можно найти в копии примера, в дополнительных материалах.
Есть одна сложность с элементом img в Сценарии 4, который не обновляется при смене контрастности во время работы приложения, как это происходит с медиа-запросами в Сценариях 1-3. Таким образом, хост-процесс приложения не перерисовывает элемент img в ответ на изменение контрастности. Для того, чтобы изменить это поведение, мы обычно заставляем хост-процесс приложения думать, что изменился URI источника, присоединяя некоторые фиктивные параметры URI. Мы можем сделать это внутри обработчика AccessibilitySettings.onhighcontrastchanged, где eventArgs.target.highContrastScheme предоставляет подходящие переменные для URI (смотрите js/scenario4.js в модифицированном примере):
var page = WinJS.UI.Pages.define("/html/scenario4.html", {
ready: function (element, options) {
var accSet = new Windows.UI.ViewManagement.AccessibilitySettings();
accSet.addEventListener("highcontrastchanged", function (e) {
var image = document.getElementById("buttonImage");
//Используем имя схемы (без пробела) в качестве фиктивного параметра URI
var params = e.target.highContrast ?
"?" + e.target.highContrastScheme.replace(/\s*/g, "") : "";
image.src = "../button.svg" + params;
});
}
});
Одно из значительных преимуществ highcontrastchanged перед прослушивателями медиа-запросов, заключается в том, что последние вызываются очень скоро после того, как произошло изменение, в тот момент, когда загрузчик ресурсов может еще не применить изменения к тому моменту, когда вы устанавливаете атрибут img.src. Это приводит к отображению не тех изображений. Событие highcontrastchanged вызывается гораздо позже, в итоге вышеприведенный код обычно работает. Тем не менее, мои эксперименты в этом направлении (с примером, исполняющимся в прикрепленном режиме и с Панелью управления, открытой в заполняющем), показали, что это не на 100% надёжно: изменение схемы контрастности – это ресурсоёмкая операция, которая вызывает много событий по всей системе, и нет гарантии, что загрузчик ресурсов успеет справиться со своей работой. По этой причине вы можете вы можете решить попросту не пользоваться всем этим, устанавливая явным образом атрибу src для показа известных файлов с конкретными именами. Модифицированный пример действительно использует подобный подход (закомментируйте код выше). Или вы можете просто использовать медиа-запросы!
Так как изображения, с которыми мы работали в предыдущем разделе, имеют формат SVG, нет необходимости поддержки различных файлов для разной плотности пикселей. Но что, если у нас есть растровая графика? Как нам скомбинировать настройки масштабирования и контраста? Об этом так же нужно будет подумать, когда мы будем заниматься локализацией в следующем разделе, так как нам так же может понадобиться использовать разные варианты для разных языков.
Это приводит нас к теме квалификаторов ресурсов (resource qualifiers), во всех подробностях об этом можно прочесть в материале "Как именовать ресурсы, используя квалификаторы" (http://msdn.microsoft.com/library/windows/apps/hh965372.aspx). Квалификаторы включают в себя масштабирование и контрастность, как мы увидим, а так же язык, направление макета, домашний регион и некоторые другие таинственные варианты.
Для того, чтобы скомбинировать квалификатор с отдельным именем файла, присоедините их все вместе, использовав знаки подчеркивания. В общей форме это выглядит как filename.qualifiername-value_qualifiername-value.ext. В итоге, изображение, имеющее имя logo.png, может иметь варианты наподобие logo.contrast-high_scale-180.png и logo.scale-100_contrast-white.png (порядок квалификаторов значения не имеет). Очевидно, с полным набором из трех или четырех вариантов масштабирования (учитывая некоторые случаи использования scale-80) и с четырьмя возможными вариантами контрастности, у нас может получиться 16 разных изображений для одного ресурса.
Образец использования этого механизма можно найти в примере "Ресурсы приложения и локализация" (http://code.msdn.microsoft.com/windowsapps/Application-resources-and-cd0c6eaa). Откройте его в Visual Studio и посмотрите в папку с изображениями. (Хотя пример показывает лишь разные варианты изображений для разных схем контрастности при 100% масштабировании, не забудьте предоставить в собственном приложении варианты для масштаба 140% в 180%; приложение "Here My Am!" для этой лекции поступает так с экраном-заставкой, плитками и логотипом.)
Когда мы займёмся темой подготовки приложения к мировому рынку, мы обнаружим, что локализованные ресурсы изображения требуют набора вариантов с разной контрастностью и масштабированием для каждого языка. Как вы можете догадываться, подобное соглашение об именовании файлов может вызвать путаницу, когда увеличивается количество файлов. К счастью, загрузчик ресурсов позволяет применять квалификаторы в именах папок, в итоге, локализованные ресурсы обычно размещаются в папках, относящихся к конкретным языкам. Больше об этом – ниже, в разделе "Часть 2: структурирование ресурсов для языка по умолчанию". Мы, кроме того, полностью избежали подобных сложностей в приложении "Here My Am!" с помощью использования элемента canvas вместо отдельных изображений для данных графических ресурсов, которые содержат текстовые сообщения (логотип не локализован).
Как и любые другие изображения в вашем приложении, изображения плиток в манифесте, изображения, отправляемые на плитку при обновлении, и изображения, используемые во всплывающих уведомлениях, учитывают установки контрастности. (С индикаторами событий проблемы нет, так как они уже монохромные и настраиваются автматически). Именование файлов изображений в манифесте с использованием квалификаторов ресурсов работает и для настроек масштабирования, и для контрастности, и для языка, как мы увидим ниже.
Полезные данные XML для плиток и всплывающих уведомлений могут ссылаться на локальные изображения с использованием URI ms-appx:///, а загрузчик ресурсов будет искать подходящий файл. Это не применимо, однако, к URI ms-appdata:///, поэтому, если вы работаете с загруженными или динамически генерируемыми изображениями, вам понадобится определять конкретные файлы самостоятельно.
Для полезных данных XML, которые могут ссылаться на удаленные изображения, установка параметра addImageQuery в значение true, как обсуждалось в Главе 2, присоединит к удаленным URI строку запроса, которая отражает масштабирование, контрастность и язык:
?ms-scale=<scale>
ms-contrast=<contrast>
ms-lang=<language>
Подробности об этом можно найти в материале "Глобализация и специальные возможности для уведомлений на плитках и всплывающих уведомлений" (http://msdn.microsoft.com/library/windows/apps/Hh831183.aspx), а так же о том, Как локализовывать строки в полезных данных XML. Мы сами всё это увидим немного позже.
На протяжении многих лет я слышал много слов, описывающих процесс подготовки приложения к различным региональным рынкам, и я могу представить, что вы тоже это слышали: локализация, локализуемость, интернационализация, глобализация и готовность к мировому рынку. Для того, чтобы быть честным, должен заметить, что разница между этими терминами некоторое время была мне не вполне ясна, но я, наконец, нашёл отличное объяснение в довольно старой книге по настольным приложениям, которая называется "Developing International Software", Dr. International (Microsoft Press, 2003). Те же идеи выражены в материале "Глобализация: шаг за шагом" (http://msdn.microsoft.com/en-US/goglobal/bb688110). Таким образом, позвольте мне начать лекцию с простого обзора этой точки зрения.
Цель, которую мы преследуем с помощью приложений для Магазина Windows – сделать их доступными на таком количестве рынков по всему миру, которое доступно в Магазине Windows. Для того чтобы это сделать, приложение нужно написать так, чтобы оно могло приспосабливаться к любому языку и культуре, с которыми оно может столкнуться. В некоторых ситуациях вам понадобиться создавать специальную версию приложения, но, к счастью, у вас может быть одно приложение с локализованными ресурсами, которое работает на большинстве рынков. Действительно, дни одноязычных приложений прошли.
Для того, чтобы достичь этой цели, вы, сначала, должны подготовить приложение к мировому рынку. Готовность к мировому рынку подразумевает, что хотя приложение изначально поддерживает лишь один язык и культуру (весьма вероятно, ваши), оно не делает никаких предположений об этих особенностях в HTML, CSS и JavaScript (и в WinRT-компонентах). Таким образом, основное приложение нейтрально по отношению к языку, культуре и рынку, принимая во внимание следующие факторы:
aria-label и img.alt, выделяется в файл ресурса, таким образом, разные ресурсы могут быть загружены для разных языков. (В наши дни использование текста в формате Unicode стало привычным, поэтому отображение текста на множестве языков – это не проблема, но помните об этом, если вы осуществляете перенос на новую платформу старого программного обеспечения или используете веб-сервисы, которые могут работать иначе).
Приложение, готовое к мировому рынку, коротко говоря, и глобализовано – с использованием API, которые учитывают региональную специфику и легко локализуемо, так как добавление поддержки для других языков не требует изменений кода, а лишь добавление новых строковых и графических ресурсов. Это больше вопрос того, как вы структурируете эти ресурсы, и как вы будете ссылаться на них в разметке и исходном коде приложения.
Процесс локализации, таким образом, это создание или приобретение подобных ресурсов, специфичных для культуры и языка, для чего существуют некоторые весьма полезные инструменты, позволяющие упорядочить работу по переводу.
В следующих разделах мы сначала рассмотрим вопросы глобализации, узнаем, как структурировать ресурсы, чтобы они были локализуемыми, и затем посотрим как работать с локализованными ресурсами. После этого мы готовы будем взглянуть на последний шаг в долгом пути создания приложения: на отправку приложения в Магазин Windows.
Помимо языка, в разных частях мира отличается представление даты и времени (в том числе – календари); представление чисел, мер (единиц), телефонных номеров и адресов; валют; размеров бумаги (об этом мы говорили в Главе 4); есть отличия в том, как сортируется (упорядочивается) текст; отличия в направлении текста и в шрифтах, которые используются для вывода текстов вместе с методами ввода.
Глобализация приложения подразумевает отсутствие предположений о том, как всё это реализуется, вместо этого нужно использовать API WinRT, которые сделают всё как нужно в зависимости от настроек текущего пользователя. И глобализация, преимущественно, означает работу с этими API.
Помимо использования API, посмотрите на само содержимое приложения, проверьте слова, фразы, выражения, которые может быть очень сложно перевести (или на потенциально политически оскорбительные), в особенности разговорные, просторечные, проверьте слэнг, метафоры, жаргон и так далее. Используйте изображения, понятные всем, которые вряд ли могут быть неправильно поняты где-то в мире (представьте себе, что вы носите футболку с подобным изображением в стране, где вы собираетесь продавать приложение!). Проявляйте осторожность при работе с картами, так как имеются разногласия между различными народами о том, где, в действительности, должны быть нарисованы их границы. Лучше ссылайтесь на "страну/регион", чем просто на "страну", так как спорные территории могут не иметь статуса страны.
Кроме того, учитывайте региональные законы, касающиеся экспорта и относящиеся к алгоритмам шифрования, так как вам может быть запрещено делать приложение доступным на некоторых рынках. Посмотрите материал "Ограничения на экспорт средств шифрования" (http://msdn.microsoft.com/library/windows/apps/hh694069.aspx). Кроме того, если вы пишете игру, следует помнить о региональных требованиях по оценке игр, которые могут привести к такому объему дополнительной работы, который выполнять невыгодно. Смотрите материал "Требования к публикации игр в Windows" (http://msdn.microsoft.com/library/windows/apps/hh452788.aspx).
Если вы используете веб-сервисы, убедитесь в том, что вы так же используете сервисы, которые соответствуют региональным особенностям расположения пользователя. Это может быть необходимо по закону в некоторых странах (особенно в том, что касается финансовых операций и карт) и часто гарантирует, что пользователи получают с данного сервиса информацию, соответствующую их региону, если только они не настроят приложение иным образом. Так же вам может понадобиться возможность передать данные о расположении пользователя и его языке подобным сервисам, в итоге, они смогут вернуть содержимое, которое уже локализовано. Кроме того, полезно для общей производительности приложения использовать сервера, которые сравнительно близко расположены к пользователю, чем те, которые находятся по другую сторону земного шара!
Наш первый шаг среди всего этого, однако, заключается в том, чтобы узнать, где, на самом деле, исполняется ваше приложение, узнать язык и культурные предпочтения пользователя. Поэтому давайте посмотрим, как это сделать.
Когда пользователь приобретает устройство под управлением Windows 8 или устанавливает Windows 8 на компьютер, она, вероятнее всего, будет настроена для страны, в которой он живет. Однако, многие пользователи говорят на нескольких языках, независимо от страны проживания и они могут захотеть работать с Windows на конкретном языке, который не имеет ничего общего с их расположением. По этой причине вам всегда следует отдельно рассматривать предпочтения пользователя от реального местоположения устройства, применяя предпочтительные настройки пользователя к тому, как ваше приложение отображает информацию, но использовать физическое расположения для управления тем, какие сервисы вы используете и другими, более функциональными аспектами.
Язык и другие предпочтения настраиваются по адресу Панель управления>Часы, язык и регион (Control Panel>Clock, Language, and Region). Здесь вы можете добавлять языки и выбирать основной (смотрите рис 16.3.), изменять методы ввода, задавать расположение (страну или территорию) и устанавливать форматы даты, времени, чисел и валюты (рис 16.4.)
(рис 16.3) Управление языками в Панели управления
Хорошо, что есть API глобализации, так как иначе иметь дело со всеми возможными здесь вариантами было бы непросто! (Обратите внимание, что изменение форматов на Рис. 6.9. повлияет лишь на те приложения для Магазина Windows, которые исполняются с использованием языка, который вы настраиваете; каждый набор пользовательских форматов относится к конкретному языку).
Основные сведения об установках пользователя доступны посредством объекта ) и через классы в пространстве Windows.Globalization (http://msdn.microsoft.com/library/windows/apps/windows.globalization.aspx). Объект GlobalizationPreferences лишь предоставляет удобные свойства. Четыре из них: ).
(рис 16.4) Диалоговые окна Панели управления для настроек форматов и региона
Кроме того, этот объект содержит строковое свойство, которое называется ). Сценарий 1 примера "Параметры глобализации" (http://code.msdn.microsoft.com/windowsapps/Globalization-preferences-6654eb36) получает и отображает эти данные. Возможно, вы захотите добавить в него код для отображения данных из currencies, так как данные по валюте он не предоставляет. Внеся в него эти изменения и добавив несколько языков в мою систему, я увидел следующее:
Вообще говоря, эти значения, это обычно именно то, что обычно нужно для обмена данными с веб-сервисом, если он предоставляет локализованные данные для приложения. Однако, пользовательские параметры языка лучше получать несколько иным образом, как мы скоро увидим.
Часто нужно знать больше подробностей по каждому из этих параметров, для чего мы можем обратиться к классам пространства имен ), например,просто содержит два строковых свойства: twelveHour и twentyFourHour, значения которых совпадают с тем, что возвращается из ) содержит строковые значения для gregorian, hebrew, hijri, japanese, julian, korean, taiwan, thai, и umAlQura. Таким образом, если вы хотите сравнить календарь, который предпочитает пользователь с каким-то конкретным, вы можете написать такой код:
var userCalendar = Windows.System.UserProfile.GlobalizationPreferences.calendars[0];
if (userCalendar == Windows.Globalization.CalendarIdentifiers.julian) {
// ...
}
При таком подходе ваш код полностью соответствует ключевому принципу глобализации, который касается того, тчо не нужно делать предположения о том, какими могут быть строки календаря.
Другие классы, связанные с глобализацией, несколько богаче по своим масштабам и функция. Класс ), экземпляр которого обычно создают с указанием конкретного тега BCP-47 tag, предоставляет такие сведения, как displayName, nativeName, languageTag, и script. Сценарий 2 вышеупомянутого примера показывает это. Класс Language так же имеет два статических члена. Один из них – это метод isWellFormed, который сообщит вам, содержит ли строка верный тег BCP-47. Второй - это свойство currentInputMethodLanguageTag, которое содержит тег BCP-47 для предпочтительного языка ввода пользователя, который может быть настроен в Панели управления, отличаясь, если нужно, от языка по умолчанию. (Смотрите ссылку Параметры (Options) в правой части Рис. 6.8; так же это показывает Сценарий 4 нашего примера).
Далее, имеется класс ), который, при создании его экземпляра без аргументов, предоставляет подробности о домашнем регионе пользователя. Вы так же можете создать экземпляр, указав конкретную строку для местоположения. В любом случае, он вернет вам displayName, nativeName, множество кодов форматов для региона (code, codeThreeDigit, codeThreeLetter, и codeTwoLetter), и currenciesInUse (массив трехбуквенныех кодов формата ISO 4217). Сценарий 3 примера коказывает эти значения для вашей конфигурации, например, так:
Класс ), в свою очередь, содержит лишь несколько значений. manifestLanguages представляет собой массив языков, определенных в манифесте приложения; вы устанавливаете их при локализации приложения. Объекты languages содержат комбинацию массива GlobalizationPreferences.languages и данных из manifestLanguages. Первый элемент в списке – это наилучшее значение для использования в приложении с учетом предпочтений пользователя, и это значение можно передать веб-сервису для целей локализации.
Далее, это свойство ) и Сценарий 13 примера "Ресурсы приложения и локализация" (http://code.msdn.microsoft.com/windowsapps/Application-resources-and-cd0c6eaa).
Последний класс, Calendar (http://msdn.microsoft.com/library/windows/apps/windows.globalization.calendar.aspx), весьма обширен и содержит слишком много членов, чтобы здесь их перечислять, многие из которых работают с форматированием или выполняют календарные расчеты. Прежде чем этим заняться, однако, давайте посмотрим шире на вопрос форматирования данных.
Если вы осмотритесь в диалоговых окнах для настройки форматов и региона (рис 16.4), вы обнаружите, что возможны тонкие настройки форматирования чисел, которые могут выглядеть пугающе, уже не говоря о форматировании даты, времени и валюты!
К счастью, классы для форматирования в WinRT учитывают все детали, так что вы можете взять значение из new Date(), например, и получить строку, которая полностью отражает предпочтенияп пользователя. Эти API так же предоставляют функции разбора, которые работают в обратном направлении.
В ), ), ), и ), которые следует всегда использовать при конверсии значений данных в строки, которые отображаются в пользовательском интерфейсе. Работа со всеми этими средствами форматирования показана в примере "Форматирование и анализ числовых значений" (http://code.msdn.microsoft.com/windowsapps/Number-formatting-and-bb10ba3d), стандартный рабочий процесс выглядит как создание экземпляра класса со специальным кодом языка или без него, установка необходимых свойств для средства форматирования (таких, как количество цифр и использование разделителей), и затем вызвать его метод format для получения строкового представления данных, или, наоборот, один из его методов parse* для превращения строки в число.
Например, для форматирования значения валюты, создадим объект класса CurrencyFormatter с идентификатором валюты (или с идентификаторов валюты, списком языков и регионом), установим параметры и затем вызовем format (js/CurrencyFormatting.js):
// Применяем значения по умолчанию для пользователя
var userCurrencyFormat =
new Windows.Globalization.NumberFormatting.CurrencyFormatter(userCurrency);
var currencyDefault = userCurrencyFormat.format(fractionalNumber);
// Применяем параметры форматирования валюты
var currencyFormatUSD = new Windows.Globalization.NumberFormatting.CurrencyFormatter("USD");
var currencyUSD = currencyFormatUSD.format(fractionalNumber);
// Применяем параметры валюты, языка и региона (Франции, затем - Ирландии)
var currencyFormatEuroFR =
new Windows.Globalization.NumberFormatting.CurrencyFormatter("EUR",
["fr-FR"], "ZZ");
var currencyEuroFR = currencyFormatEuroFR.format(fractionalNumber);
var currencyFormatEuroIE =
new Windows.Globalization.NumberFormatting.CurrencyFormatter("EUR",
["gd-IE"], "IE");
var currencyEuroIE = currencyFormatEuroIE.format(fractionalNumber);
// Включая дроби с целым числом
var currencyFormatUSD1 =
new Windows.Globalization.NumberFormatting.CurrencyFormatter("USD");
currencyFormatUSD1.fractionDigits = 2;
var currencyUSD1 = currencyFormatUSD1.format(wholeNumber);
// Группируем целые числа
var currencyFormatUSD2 =
new Windows.Globalization.NumberFormatting.CurrencyFormatter("USD");
currencyFormatUSD2.isGrouped = 1;
var currencyUSD2 = currencyFormatUSD2.format(fractionalNumber);
Выходные данные этого кода выглядят следующим образом:
Другие средства форматирования чисел выглядят похожим образом, поэтому я предлагаю вам самостоятельно ознакомиться с примером и документацией.
Для форматирования даты и времени мы можем обратиться к пространству имен ), где можно найти класс ) вместе со множеством перечислений для различных способов форматирования секунд, минут, часов, дней, месяцев и лет. Для использования данного API, вы создаете объект для форматирования, задаете необходимые форматы и применимые языки. (У него не меньше восьми разных конструкторов!). Затем вы выбираете параметры, наподобие ), я думаю, небольшого фрагмента его кода будет вполне достаточно (из Сценария 2, js/stringtemplate.js):
var mydatefmt1 = new Windows.Globalization.DateTimeFormatting.DateTimeFormatter(
"month day");
var mytimefmt1 = new Windows.Globalization.DateTimeFormatting.DateTimeFormatter(
"hour minute ");
var dateToFormat = new Date();
var mydate1 = mydatefmt1.format(dateToFormat);
var mytime1 = mytimefmt1.format(dateToFormat);
Другой фрагмент кода из SDK, который сюда подходит, это пример "Подробные сведения о календаре и вычисления" (http://code.msdn.microsoft.com/windowsapps/Calendar-details-and-math-b1683bb7). Как было упомянуто выше в данной лекции, когда я говорил о времени истечения срока пробной лицензии приложения и покупок из приложения, приложение, готовое для мирового рынка, не должно делать предположений о том, как вычисляются или сравниваются временные отрезки, так как это может различаться в зависимости от регионального календаря. Именн поэтому весьма обширный класс Windows.Globalization.Calendar (http://msdn.microsoft.com/library/windows/apps/windows.globalization.calendar.aspx) содержит десять различных методов add*, которые находятся в диапазоне от addNanoseconds до addEras, вместе с его методами compare и compareDateTime (и множество механизмов для получения текстов, связанных с календарем). Другими словами, навсегда запомните сейчас, что вы никогда больше не будете использовать арифметические операции для работы со значениями даты и времени, так как они не работают соответствующим образом в каждом регионе. Даже в США вы придете к неправильным значениям, так как не учтете что-то вроде перехода на летнее время, когда число часов в двух днях каждого года, на самом деле, не 24!
Так же, как приложения, готовые к мировому рынку, не могут строить предположения о сравнении значений даты и времени, они не могут делать и предположения о том, как сортируются строки. Проще говоря, каждый язык имеет свой собственный способ сортировки, который не обязательно имеет что-то общее со значениями кодов символов. Суть здесь в том, что вам никогда не следует выполнять сортировку по подобным значениям, всегда вместо этого используйте API, учитывающие языковые особенности.
Для приложений для Магазина Windows, написанных на HTML, CSS и JavaScript, вы можете использовать метод ), который уже встроен в строки (даже для отдельных символов). Он производит сравнение, основываясь на текущем языке пользователя. Вы так же можете использовать методы строк ) и ). В Главе 5 курса "Введение в разработку приложений для Windows 8 с использованием HTML, CSS и JavaScript", в разделе, посвященном примеру группировки элементов ) для правильной группировки по первым символам заголовков элементов. Вы можете сравнить исходный пример в SDK с модифицированным примером, который находится в дополнительных материалах к вышеупомянутой лекции, для того, чтобы увидеть, как этот код был глобализован.
Благодаря ), то можете увидеть, что страницы вроде html/scenario2.html содержат подобную разметку:
<div id="scenario2Document">
<h2 lang="hi" id="scenario2Heading" contenteditable="true">
?????? ????? ????????
</h2>
<p lang="hi" contenteditable="true">
?????? ????? ???????? ??? ???? ???? ???? ?????? ????? ????? ???? ??????
???????? ???????? ???? ???? ???? ???? ???? ????? ???? ????? ???????
????????? ???? ???? ????? ?????????? ??? ?????? ?????????? ????????
??? ???? ???? ????? ??????? ??????? ???? ?????? ????? ???? ?????? ???????
???? ???? ????? ????? ???? ??? ???? ???? ????? ????? ????
</p>
</div>
Вот как это выглядит (и если вы читаете на Хинди, вы увидите, что это бессмысленный текст):
Что этот пример, на самом деле, демонстрирует, так это использование объекта ), который предоставляет особые рекомендации по шрифтам для различных частей пользовательского интерфейса. Созданный с использованием конкретного тега BCP-47, объект содержит множество свойств, каждое – типа LanguageFont, как, например, uITextFont и uIHeadingFont (снова обратите внимание на странное изменение регистра). Каждый объект LanguageFont, в свою очередь, содержит такие свойства, как fontFamily, fontStretch, fontStyle, fontWeight, и scaleFactor. С помощью пары вспомогательных функций в js/langfont.js, которые расположены в пространстве имен WinJS.UI , не являясь частью WinJS, эти рекомендации применяются к элементам DOM путём простой установки соответствующего стиля для этих элементов.
Вам должно быть понятно, что эти рекомендации шрифтов – лишь улучшения и в них нет необходимости для реализации базовой функциональности. Как показывает Сценарий 4 примера, базовый английский шрифт (c Unicode-символами, конечно), примененный к смешанному английско-японскому тексту, выводит японский текст, но, возможно, неоптимально. Применение рекомендованного шрифта выполняет такое улучшение.
Другой аспект, касающийся работы с различными шрифтами и языками заключается в том, как всё это влияет на общий макет приложения. Этому посвящен материал документации "Настройка макета и шрифтов для различных языков и поддержка макетов с написанием справа налево" (http://msdn.microsoft.com/library/windows/apps/hh967757.aspx), однако, позвольте мне сделать сводку по этому материалу и добавить кое-что еще.
Во-первых, приложения, готовые к мировому рынку, оставляют дополнительное место для различных фрагментов содержимого, наподобие заголовков и подписей, так как слова и фразы длиннее в некоторых языках и короче в других. Общее правило – оставлять как минимум на 30% больше места, чем вам нужно для строк на английском, и до 300% для по-настоящему коротких предложений и отдельных слов. Например, английское слово "wrench" (гаечный ключ) переводится на немецкий как "Schraubenschl?ssel"; слово "click" (щелчок) (в этом я доверился Bing Translator), переводится на греческий как "????? ???? ??? ??????." В некоторых случаях вам может понадобиться перенос слов.
Для всех подобных целей вы можете использовать селекторы псевдо-классов :lang()/:-ms-lang() (http://msdn.microsoft.com/library/windows/apps/Hh996886.aspx) в CSS для настройки стилей наподобие width так, как нужно для конкретных языков. Не забудьте протестировать ваше приложение с этими языками, или протестируйте его с использованием псевдо-языка (смотрите "Тестирование с помощью псевдо-языка" далее"
Во-вторых, различные языки располагают текст в направлении, отличном от направления слева направо (и сверху вниз), принятое в английском и во многих индоевропейских языках. Арабский и иврит, например, читаются справа налево (RTL) вместо чтения слева направо. В некоторых символы располагаются сначала сверху вниз, потом – справа налево.
Подготавливая свое приложение для RTL-языков (учитывая, что подобные рынки очень важны), вам следует реализовать в своем макете то, что называется "зеркальным отражением". Это подразумевает реверсирование вашего макета, включая изображение, направление кнопки "Назад", направление анимаций, сдвига содержимого и так далее.
К счастью, HTML и CSS-макеты автоматически реализуют подобное, и таблицы стилей WinJS, ui-light.css and ui-dark.css, соответствующим образом задают стиль CSS direction (http://msdn.microsoft.com/library/windows/apps/hh996832.aspx), как показано ниже (это то, что вам следует использовать на уровне элементов для RTL-языков, а не обычное выравнивание):
html:-ms-lang(ar, dv, fa, he, ku-Arab, pa-Arab, prs, ps, sd-Arab, syr, ug, ur, qps-plocm) {
direction: rtl;
}
На самом деле, ознакомьтесь поближе с таблицами стилей WinJS, и вы найдете много настроек, выполненных для RTL-языков :-ms-lang, в частности, поля и отступы. Поэтому, если вы используете HTML, CSS и JavaScript, в том числе – встроенные элементы управления, основная часть техники зеркального отражения реализуется автоматически. Приложение "Here My Am!", например, просто работает на иврите.
Что касается изображений, то вы можете инвертировать их, применяя стиль ), кое-что мы подробнее рассмотрим в следующем разделе.
Иногда вам понадобится задать обратное направление для некоторой части текста, как при смешивании языков в одном и том же абзаце. Для этого вы можете применить стиль unicode-bidi (http://msdn.microsoft.com/library/windows/apps/hh996988.aspx) вместе с параметром direction. (Заметьте, что цифры обычно нейтральны в смысле направления, они принимают направление элементов, которые их содержат, поэтому вам может понадобиться установить параметры направления их расположения отдельно). Аналогичным образом, вы можете так же использовать стиль -ms-writing-mode (http://msdn.microsoft.com/library/windows/apps/Hh997001.aspx) для того, чтобы задать практически любое направление текста, например, для представлений классической китайской, японской или корейской поэзии
Как только ваше приложение было подготовлено к мировому рынку, это означает, что оно может поддержать практически любой язык и региональные установки, которые вы ему передадите, следующий шаг заключается в том, чтобы убедиться, что языкозависимые ресурсы в приложении чётко отделены от HTML, CSS и JavaScript, и размещены там, где их может найти средство загрузки ресурсов Windows (так же упоминаемое как Система управления ресурсами, Resource Management System).
Прежде чем продолжать, вот отличный материал в документации по этой теме: "Подготовка к локализации" (http://msdn.microsoft.com/library/windows/apps/hh967759.aspx), который содержит советы по переводу и другие подробности. Непродуктивно повторять всё это здесь, конечно, поэтому я, вместо этого, хочу разбить руководство на два шага, которые вы можете реализовать для своего приложения и иго языка по умолчанию прежде чем добавлять поддержку дополнительных языков.
Примечание. Загрузчик ресурсов поддерживает разреженную локализацию (sparse localization) для языков, между которыми имеются лишь небольшие различия. Это значит, что при работе с языками, наподобие американского английского (en-US) и британского английского (en-GB), большая часть ресурсов приложения может быть назначена en-US, в то время, как en-GB-ресурсы будут отражать различия, вроде "color" и "colour", "favorite" и "favourite" или наоборот. Так как каждый ресурс разрешается индивидуально, в соответствии с предпочтениями пользователя, приложение, выполняющееся в контексте языка en-GB обнаружит специфические данные, а в противном случае загрузчик использует ресурсы для языка en-US. Существует так же поддержка работы с языковыми исключениями, с помощью ресурсов отмеченных неопределенным тегом und. Смотрите материал "Управление языковыми и региональными параметрами" (http://msdn.microsoft.com/library/windows/apps/Hh967758.aspx), шаг 4 (ближе к концу) и материал "Сопоставление языков" (http://msdn.microsoft.com/library/windows/apps/jj673578.aspx).
Первый шаг в подготовке к локализации заключается в переносе строк, зависимых от языка или региона, из исходного кода в файлы строковых ресурсов и вставка ссылок на данные файлы там, где это нужно. В следующем разделе мы зададим структуру папок для этих файлов и ресурсов изображений, которые будут использованы в локализованной версии.
Для того, чтобы создать ваш первый файл строковых ресурсов, щёлкните правой кнопкой по вашему проекту в Обозревателе решений Visual Studio, выберите команду Добавить>Создать элемент (Add>New Item), и затем выберите Файл ресурсов (Resources File) (.resjson). Хотя вы можете изменить имя файла, просто оставьте его сейчас в значении по умолчанию resources.resjson. Нажмите Добавить (Add), и файл будет создан в корневом разделе вашего проекта, где он и будет оставаться до Части 2.
С опущенными комментариями, которые находятся в верхней части, этот файл выглядит так:
{
"greeting" : "Hello World!",
"_greeting.comment" : "This is a comment to the localizer"
}
Как видите, файл – это обычны JSON, где каждое свойство имеет строковой идентификатор и строковое значение. Любой resjson0 файл может иметь столько свойств, сколько нужно.
Очевидна так же и взаимосвязь между двумя вышеприведенными записями. Первая, в форме
<identifier> : <value>
это реальный строковой ресурс, который задает соответствие действительного JSON-идентификатора(пробелы не применяются) строковому значению. Это то, что загрузчик ресурсов использует для замены ссылки на идентификатор строковым значением.
Любая запись, которая начинается с символа подчеркивания, такая, как обычно применяемая
<_identifier.comment> :<value>
игнорируется загрузчиком ресурсов. Подобные записи предоставляют заметки для переводчика, чтобы он полностью понимал, как используется строка, и то, какие её части не следует переводить. Второй необязательный тип записей, это
<_identifier.source> : <value>
который предоставляет исходную строку на языке по умолчанию, что очень полезно для справочных целей.
Если вы хотите взглянуть на более обширные файлы resjson, откройте пример "Ресурсы приложения и локализация" (http://code.msdn.microsoft.com/windowsapps/Application-resources-and-cd0c6eaa) и посмотрите в папку strings для конкретного языка. В файле ja/resources.resjson, например, вы увидите строковые ресурсы вместе с комментариями и исходными текстами записей:
{
"displayName"
: "???????? ???? JS SDK ????", "_displayName.source"
: "Application Resources JS SDK Sample", "_displayName.comment"
: "Don't change 'SDK'",
"description"
: "???????? ???? JS SDK ????", "_description.source"
: "Application Resources JS SDK Sample", "_description.comment"
: "Don't change 'SDK'",
}
Возвращаясь к вашему собственному приложению и имея новый файл resources.resjson, мы готовы продолжать, выполнять поиск и замену в проекте приложения, искать локализуемые строки, извлекать их в ресурсный файл и заменять их в исходных файлах соответствующими ссылками. Три основных места, которые нам нужно просмотреть, это ваши HTML-файлы, JavaScript-файлы и манифест приложения. Для целей демонстрации, я показал, что я сделал в приложении "Here My Am!", с которым мы работаем на протяжении курса (к нему я добавил файл resources.resjson).
Примечание. CSS-файлы могут содержать страковые литералы в стилях content и quotes; однако, разрешение ресурсов из CSS-файлов для приложений для Магазина Windows в Windows 8 не поддерживается. Локализация в CSS должна быть выполнена с помощью псевдо-селекторов :lang и :-ms-lang.
JavaScript. Начнем с JavaScript, где вам нужно просмотреть код в поиске строковых литералов, включая те, которые выводятся в элемент canvas. В "Here My Am!" я нашёл лишь пару локализуемых строк, а именно, имя папки, используемое в Библиотеке изображений, а так же – заголовок и описание, используемое при форматировании текста для контракта Общий доступ и динамических плиток: (pages/home/home.js):
var folderName = " HereMyAm ";
data.properties.title = " Here My Am! ";
return "At latitude " + lat + ", longitude " + long
return "At (" + lat + ", " + long + ")"
А так же команды для раздела Параметры в js/default.js:
app.onsettings = function (e) {
e.detail.applicationcommands =
{
"about": { title: "About", href: "/html/about.html" },
"help": { title: "Help", href: "/html/help.html" },
"privacy": { title: "Privacy Statement", href: "/html/privacy.html" }
};
WinJS.UI.SettingsFlyout.populateSettings(e);
};
Обратите внимание на то, что в home.js строки на английском используются для показа информации об исключениях, но так как они нужны лишь для отладочных целей, их локализовывать не нужно.
После извлечения других строк в файл resources.resjson, мы приводим его к следующему виду, где я использовал обычные комментарии для того, чтобы указать на то, где используется строка. Обратите внимание на то, что я использовал форматную строку при создании описания местоположения для чудо-кнопки Общий доступ и плиток, вместо того, чтобы задавать эту конструкцию в коде (смотрите функцию formatLocation в js/home.js для того, чтобы увидеть, как это используется):
{
// pages/home/home.js
"foldername" : "HereMyAm",
"share_title" : "Here My Am!",
"location_formatShort" : "At (%s, %s)",
"_location_formatShort_comment" : "Used to format a short location as in 'At (120, 45)",
"location_formatLong" : "At latitude %s, longitude %s",
"_location_formatLong_comment" :
"Used to format a long location, 'At latitude 120, longitude 45",
// default.js
// Команды панели параметров
"about_command" : "About",
"help_command" : "Help",
"privacy_command" : "Privacy Statement",
}
Настоятельно рекомендую, чтобы вы организовали ваши записи по файлам исходного кода, как здесь, и так же вы можете использовать несколько файлов ресурсов, если хотите, как показано в следующем разделе. Так же будьте осторожны с повторным использованием тех же самых строк, которые появляются в нескольких местах. Если это тот же самый пользовательский интерфейс, отображаемый с тем же самым намерением, то всё нормально, но если контекст использования отличается, лучше дублировать строку, так как на другие языки она может переводиться по-другому. В вышеприведенных ресурсах, обратите внимание на то, что я включил комментарий для location_formatShort, так как слово "At" само по себе, возможно, нуждается в некотором контексте для верного перевода.
Когда строки выделены в виде ресурсов, теперь мы можем использовать загрузчик ресурсов для получения этих строк во время выполнения программы. Это можно сделать двумя способами. Первый – с использованием API WinRT, а именно, ):
var loader = new Windows.ApplicationModel.Resources.ResourceLoader();
var text = loader.getString('location_formatShort');
или, проще, с использованием функции-оболочки WinJS.Resources.getString (http://msdn.microsoft.com/library/windows/apps/hh701590.aspx):
var text = WinJS.Resources.getString('location_formatShort').value;
Это работает и в веб-контексте, где WinRT недоступна (Смотрите Сценарий 12 примера "Ресурсы приложения и локализация" (http://code.msdn.microsoft.com/windowsapps/Application-resources-and-cd0c6eaa) ). Обратите внимание на то, что getString возвращает объект, который содержит свойство value со строкой, а так же свойство lang и флаг empty, указывающий на то, что ресурс не был найден.
Метод WinJS, который записывается в одну строку, очевидно, полезен в случае наподобие наших команд параметров, так как мы можем вызывать его внутри. Таким образом, в нашем коде мы просто заменяем строковые литералы на вызовы WinJS, как, например, в pages/home/home.js:
data.properties.title = WinJS.Resources.getString('about_command').value;
И так, внутри объекта для команд панели чудо-кнопки Параметры:
"about": { title: WinJS.Resources.getString('about_command').value,
href: "/html/about.html" },
Обратите внимание на то, что WinJS, оптимизированный для обычных сценариев, поддерживает загрузку строк лишь на языке пользователя по умолчанию. С другой стороны, класс WinRT ResourceLoader обладает гораздо большей гибкостью и может загружать строки на любом заданном языке. Вам нужно использовать данное API, если ваши нужды превышают то, что предоставляет WinJS.
И это всё, что нужно сделать для JavaScript. Если вы сделали подобные изменения в своем приложение, самое время выполнить команду Построение>Построить решение (Build>Build Solution) в Visual Studio. По этой команде файл ресурсов resources.resjson будет скомпилирован в более эффективный двоичный формат и назван resources.pri, записи, имя которых начинается с символа подчеркивания, отбрасываются. Выполнение периодического построения (без запуска приложения) это хороший подход при работе с ресурсами, благодаря которому вы можете обнаружить любые проблемы в ваших файлах, такие, как дублирование записей или синтаксические ошибки. Затем вы можете запустить приложение для того, чтобы увидеть загрузчик ресурсов в действии – в основном не видя различий между тем, что получилось сейчас, и тем, что было раньше! Не забудьте протестировать все ветви кода, которые были вовлечены в работу, для того, чтобы убедиться, что все строки загружаются соответствующим образом.
Манифест. Обратимся теперь к манифесту, где всё даже проще, так как здесь не используется код. Текстовые фрагменты, которые могут нуждаться в локализации, это следующие:
Пока мы работаем с манифестом, обратите внимание на параметр Язык по умолчанию (Default Language) на закладке Интерфейс приложения(Application UI). Это то, что определяет язык приложения по умолчанию или резервный (fallback) язык, если пользователь запускает приложение с языком, который не поддерживается в ресурсах. Мы так же вернемся к изображениями в манифесте в следующем разделе.
Найдя все строки в манифесте, извлеките их в файл resources.resjson, задав им подходящие идентификаторы. Опять же, если у вас есть какие-то сроки в манифесте, которые соответствуют похожим строкам где-то еще в приложении, тщательно оцените их на предмет того, можно ли использовать для них те же ресурсы. Если вы сомневаетесь, храните их раздельно, так как подобная избыточность незначительна. В случае с приложением "Here My Am!", отображаемое имя приложения и строка, используемая для заголовка главной страницы выглядят одинаково и используются похожим образом, поэтому данные параметры могут ссылаться на один и тот же ресурс.
Для того, чтобы сослаться на ресурсы в манифесте, используйте синтаксис ms-resource:<identifier>. Например, я поместил значение из параметра Интерфейс приложения>Отображаемое имя (Application UI>Display Name) в файл ресурсов и назвал его app_title, в итоге, в данном поле редактора манифеста я просто ввожу ms-resource:app_title. То же самое я делаю для описания и отображаемого имени пакета.
Как только вы выполнили эти изменения, запустите приложение и убедитесь в том, что текст на плитках, если вы используете его, отображается верно. Вы можете временно установить параметр Интерфейс приложения>Показывать имя (Application UI>Show Name) в значение Все значки(All Logos) и проверить, но не забудьте вернуть всё обратно!
Как описано в материале "Глобализация и специальные возможности для уведомлений на плитках и всплывающих уведомлений" (http://msdn.microsoft.com/library/windows/apps/Hh831183.aspx), полезные данных XML для плиток и всплывающих уведомлений испльзуют синтаксис ms-resource: для идентификации строковых ресурсов в текстовых элементов. Это вызовет механизм поиска загрузчика ресурсов при выводе плитки, и это работает независимо от того, было ли отправлено уведомление локально, получено с веб-сервиса или принято в виде push-уведомления. Веб-сервисам лишь нужно использовать соответствующие идентификаторы ресурсов приложения.
Веб-сервис так же может напрямую отправлять локализованные обновления плиток. В таком случае приложение обычно присоединяет строку запроса в URI сервиса, отражающую необходимый язык, обновляя при необходимости эти параметры при изменении языка (смотрите "Чистовая отделка локализации" для того, чтобы узнать подробности). Так же приложение может скомбинировать это с использованием региональных веб-сервисов, что помогает в локализации данных обновлений.
HTML. Последнее место, где нам нужно искать строки, это наш HTML-код, который я оставил напоследок, так как работа с ним сложнее, чем другая. Работая с HTML нужно внимательно очистить разметку от любых заданных в ней текстов, которые видимы в пользовательском интерфейсе. Проверьте основное содержимое таких элементов, как p, h1, span, div, button, option, и так далее, так же, как и значения атрибутов title, alt, aria-label, и так далее. Кроме того, посмотрите в элементах управления WinJS, наподобие панели приложения и всплывающих элементов на предмет любых встроенных в них URI, которые вам хотелось бы локализовать, включая ссылки на сервисы, которые вы используете и на содержимое, которое вы показываете в iframe. Обратите внимание, что элементы title в заголовке страницы не отображаются, поэтому не нуждаются в локализации.
В приложении "Here My Am!" я обнаружил множество строк в pages/html/home.html, которые я выделил:
<header id="header" aria-label="Header content" role="banner">
<section id="section" aria-label="Main content" role="main">
<div id="photoSection" class="subsection" aria-label="Photo section">
<h1 class="titlearea win-type-ellipsis">
<span class="pagetitle">Here My Am! (8)</span>
</h1>
<h2 class="group-title" role="heading">Photo</h2>
<img id="photo" class="graphic" src="/images/taphere.png"
alt="Tap to capture image from camera" role="img" />
<div id="locationSection" class="subsection" aria-label="Location section">
<h2 class="group-title" role="heading">Location</h2>
<div id="floatingError" class="win-type-x-large">
Unable to obtain geolocation; check
<br />permissions and use the app bar to try again.
</div>
<div id="retryFlyout" data-win-control="WinJS.UI.Flyout" aria-label="Trying geolocation"
data-win-options="{anchor: 'mapDiv', placement: 'bottom', alignment: 'center'}">
<div class="win-type-large">Attempting to obtain geolocation...</div>
</div>
Где я так же заметил, что мне нужно локализовать изображение taphere.png, так как оно содержит текст, но это в следующем разделе. В default.html, я так же обнаружил подписи и всплывающие подсказки в атрибутах data-win-options команд Панели приложения (для краткости я опустил часть разметки):
<div id="appbar" data-win-control="WinJS.UI.AppBar" data-win-options="">
<button data-win-options="{id:'cmdPickFile', label:'Load picture', icon:'browsephotos',
section:'global', tooltip:'Load a picture through the file picker'}">
</button>
<button data-win-options="{id:'cmdRecentPictures', label:'Recent pictures', icon:'pictures',
section:'global', tooltip:'Browse recent pictures taken in the app'}">
</button>
<button data-win-options="{id:'cmdRefreshLocation', label:'Refresh location', icon:'globe',
section:'global', tooltip:'Refresh your location'}">
</button>
</div>
Совет. Подготавливаясь к локализации, выясните, имеют ли значки на Панели приложения универсальное значение. Если нет, их так же нужно локализовать. К счастью, значения значков имеют строковой формат и могут быть локализованы, в таком случае их нужно воспринимать так же, как подписи и всплывающие подсказки.
Другие файлы в приложении, которые требуют внимания, это все файлы в папке HTML, которые используются для панели чудо-кнопки Параметры. Работая с подобными командами, будьте особенно внимательны с короткими заголовками подписей, которые могут быть элементами div среди другого кода. Не упустите ничего!
Как только вы найдете строки, скопируйте их, как и ранее, в resources.resjson. Работы по копированию и вставке может быть довольно много, поэтому соберитесь с духом и сделайте это. В подобных строках может быть и HTML – он просто добавляется в разметку и выводится так же, как если бы вы присоединили его к свойству наподобие innerHTML, но не включайте туда окружающие теги (скоро они нам понадобятся). Например, в html/about.html у меня есть множество элементов p с текстом:
<p>Here My Am!<br />Version 1.0.0.0<br /></p>
Для данного элемента я создал такую стоку в файле ресурсов (без тега p):
about1" : "Here My Am!<br />Version 1.0.0.0<br />",
А теперь самое интересное: как сослаться на строковой ресурс в разметке. Если вы немного подумаете, то окажется, что нам может понадобиться запустить некий код, который просмотрит разметку и заменит ссылки, которые мы сделали, на соответствующие строки ресурсов. Хм. Не видели ли мы что-то подобное раньше? Да, на самом деле. Работая с элементами управления, мы добавляли в разметку атрибуты data-win-control и использовали WinJS.UI.processAll или WinJS.UI.process для выполнения кода по созданию экземпляров элементов управления. У нас есть нечто подобное и для ресурсов: атрибут data-win-res и WinJS.Resources.processAll, последний должен быть вызван в методе ready каждой страницs или где-нибудь еще при загрузке HTML-содержимого, например, для Панели приложения, например, в обработчике активации приложения после WinJS.UI.processAll (то есть, экземпляры элементов управления уже будут созданы).
Вот, что нужно сделать в разметке:
data-win-res="{<attribute>
: '<identifier>
'}" где <attribute>
это исходное имя атрибута, а <identifier>
соответствует желаемой строке в файле ресурсов и заключен в одинарные кавычки.
<attribute> :'<identifier>' с помощью запятой.
textContent для элементов div, p, или span. Если строка содержит разметку, используйте вместо этого innerHTML, но только по необходимости, так как textContent гораздо быстрее.
{attributes: {'<attribute>
' :'<identifier>
'}} в значении data-win-res, используя одинарные кавычки вокруг <attribute>
. С помощью такого подхода можно скомбинировать локализацию и реализацию специальных возможностей.
data-win-options, разместите их в data-win-res с использованием синтаксиса {winControl: {<property>
: '<identifier>
'}}. Несколько свойств, опять же, разделяются запятыми во внутренних фигурных скобках { }.
Вот примеры модификации разметки, приведенной ранее:
| Исходная разметка | Измененная разметка |
|---|---|
<img id="photo" class="graphic" src="/images/taphere.png" alt="Tap to capture image from camera" role="img" />
|
<img id="photo" class="graphic" src="/images/taphere.png"
data-win-res="{alt: 'photo_alt'}" role="img" /> |
<span class="pagetitle">Here My Am! (8)</span>
|
<span class="pagetitle"
data-win-res="{textContent : 'app_title'}"></span>
|
<div id="locationSection" class="subsection" aria-label="Location section">
|
<div id="locationSection" class="subsection" data-win-res="{attributes: {'aria-label' :
'aria_location'}}" >
|
<div id="floatingError" class="win-type-x-large">
Unable to obtain geolocation; check<br />permissions and use the app bar to try again. |
<div id="floatingError" class="win-type-x-large" data-win-res="{innerHTML : 'error_obtaingeoloc'}"> |
<button data-win-control="WinJS.UI.AppBarCommand" data-win-options="{id:'cmdPickFile',
label:'Load picture', icon:'browsephotos', section:'global',
tooltip:'Load a picture through the file picker'}">
|
<button data-win-control="WinJS.UI.AppBarCommand" data-win-options="{id:'cmdPickFile', icon:'browsephotos', section:'global'}"
data-win-res="{winControl: {label : 'appbar_label1',
tooltip : 'appbar_tooltip1'}}">
|
Когда WinJS.Resources.processAll обходит DOM, он, на самом деле, не удаляет атрибуты data-win-res attributes; он лишь обрабатывает их значения и добавляет к элементам другие атрибуты, которые содержат строковые ресурсы. Преимущество подобного подхода заключается в том, что последующий вызов processAll пройдёт по DOM и обновит все эти строки. Это означает, что если вы обрабатываете событие WinJS.Resources. oncontextchanged, которое сообщает вам об изменении языка, вы можете снова вызвать processAll и ваш пользовательский интерфейс будет отображен с использованием нового языка! Мы добавим этот код позже, когда мы добавим в приложение "Here My Am!" еще несколько языков.
Это так же означает, что если вы хотите произвести привязку данных WinJS, используя строки, которые соответствуют вашим ресурсам, просто включите атрибуты ) (html/scenario8.html and js/scenario8.js):
HTML: <p id="messageCount" data-win-res="{innerHTML: 'scenario8MessageCount'}">
Resources: "scenario8MessageCount" : "You have <span
data-win-bind=\"innerText:count\"></span> message(s)",
И с помощью этого (исключая последующей врезки, которую я добавил ниже), мы готовы к следующему шагу, к работе с графическими ресурсами и к локализации всего того содержимого, которое мы извлекли.
Во всем этом та часть разметки, которая предназначена для HTML-страниц всплывающих элементов для настройки параметров, а именно, about.html, help.html, и privacy.html в папке проекта HTML, вызывает наибольшую сложность. Эти страницы не загружаются до тех пор, пока не будет активирована чудо-кнопка Параметры, и так как это происходит в WinJS, мы можем использовать событие всплывающего элемента beforeshow для вызова WinJS.Resources.processAll для разметки всплывающего элемента. Для того, чтобы перехватить это событие, я добавил onbeforeshow : beforeShow в каждую строку data-win-options и затем данный код с тегом script в конце элемента body:
function beforeShow() {
WinJS.Resources.processAll();
}
beforeShow.supportedForProcessing = true;
Последняя строка здесь необходима, так как WinJS вызовет WinJS.UI.processAll когда страница будет загружена. В любом случае, это хорошо работает для строковых ресурсов, с одним исключением. В privacy.html, (подробнее об этом – в Главе 2 курса "Пользовательский интерфейс приложений для Windows 8, созданных с использованием HTML, CSS и JavaScript"), я использовал iframe для загрузки удаленной страницы с соглашением о конфиденциальности. Так как и она должна быть локализована, я разместил URI в строковые ресурсы и попытался загрузить его как и прочие строки:
<!-- Это не работает -->
<iframe data-win-res="{src : 'privacy_URI'}" height="600"></iframe>
Однако это привело к исключению в WinJS.Resources.processAll, которое сообщало о том, что что-то не было помечено как supportedForProcessing. И что? Только функции так маркируют, и я не мог думать о том, что это относится и к iframe. Оказалось, что элементы iframe специально блокируются в методах WinJS processAll , как и немаркированные функции. В результате, вы просто не можете использовать data-win-res с iframe!
К счастью, простое решение заключается в том, чтобы назначить элементу iframe id (privacyFrame), загрузить строку самостоятельно в обработчике beforeshow и затем установить атрибут iframe.src:
document.getElementById("privacyFrame").src = WinJS.Resources.getString('privacy_URI').value;
В предыдущем разделе мы создали лишь один файл resources.resjson в корневой папке проекта и мы отложили работу с изображениями. Следующий шаг заключается в улучшении структуры проекта, что позволит нам добавлять локализованные ресурсы для дополнительных языков, включая изображения.
Начнем со строк, выполните следующие шаги:
Если сейчас вы снова запустите приложение, вы должны увидеть, что всё работает. Если вы вернетесь к вышеупомянутому материалу "Как именовать ресурсы, используя квалификаторы" (http://msdn.microsoft.com/library/windows/apps/hh965372.aspx), вы увидите, что загрузчик ресурсов совершенно счастлив, если вы используете квалификаторы наподобие кодов BCP-47 в качестве имен папок. Он обычно просматривает все имена папок в поисках квалификаторов, поэтому вы можете создавать более глубокую иерархию для того, чтобы сортировать ресурсы так, как вам хочется. Таким образом, вы можете сначала отсортировать ресурсы по контрасту и масштабированию, если нужно, и включить суффиксы языков в имена файлов (с использованием формата lang-<BCP-47 тег="">). Более того, вы можете создать дополнительные файлы .resjson в данных папках и делает еще некоторые интересные вещи. Смотрите врезку "Дополнительные файлы строковых ресурсов".
В любом случае, то что вы сейчас сделали, переместив ваши ресурсы в папку для языка по умолчанию, установленному в качестве резервного языкового ресурса – это то, что загрузчик ресурсов будет обращаться к ним, если он не сможет найти более подходящих ресурсов для текущего языка пользователя. Находить совпадения, это, на самом деле, сложный процесс, где загрузчик ресурсов измеряет нечто вроде "расстояния" между предпочтениями пользователя и доступными ресурсами и выбирает то, что ближе к предпочтениям. Это делает возможным выбрать, например, en-GB как более близкий к en-AU чем en-US. В общем случае, таким образом, это означает, что при поиске для конкретного языка сначала будет использованы ресурсы с квалификатором de-DE (немецкий язык), затем – следующий ближайший язык, использующий квалификатор de, а затем будет осуществлен переход к языку по умолчанию (если нет ресурсов для других языков пользователя). Короткий вывод из всего этого заключается в том, что вам всегда следует помнить о том, что идентификаторам языков, заданным в манифесте, соответствует полный набор ресурсов. Тогда, если даже вы не локализуете некоторые из этих ресурсов (например, для точного соответствия культурным особенностям), хотя бы один из таких ресурсов будет найден). Для получения полного представления по этому вопросу обратитесь к материалу "Сопоставление языков" (http://msdn.microsoft.com/library/windows/apps/jj673578.aspx) в документации.
И WinRT и WinJS могут работать с дополнительными файлами строковых ресурсов (.resjson), позволяя вам, если нужно, организовывать строковые ресурсы в нескольких файлах. Например, строки с сообщениями об ошибках обычно выделяют в файл errors.resjson. Ссылаясь на строковой идентификатор, находящийся в одном из таких дополнительных файлов, всё, что нужно – использовать синтаксис
/<file> /<identifier>
вместо простого ).
С файлами .resjson можно делать и еще кое-что, добавляя в их имена квалификаторы для схем высокой контрастности, масштабирования, указывающие на домашний регион, и так далее, и даже организовывать эти файлы в любой из существующих папок. Это показано в Сценарии 13 того же самого примера, где есть множество разных файлов .resjson в папке strings/scenario13, имя каждого из которых имеет вид scenario13.<qualifiers>.resjson. Так как имя папки не использует стандартных квалификаторов, вам нужно сделать кое-что еще, чтобы со всем этим работать, использовать API Windows.ApplicationModel.Resources.Core.ResourceManager (http://msdn.microsoft.com/library/windows/apps/windows.applicationmodel.resources.core.resourcemanager.aspx), но этим стоит заниматься, если вы настоящий ресурсный наркоман!
В случае с изображениями, мы уже видели, что если у нас есть папка images и размещаете в ней файлы наподобие logo.contrast-high_scale-140.png, вы можете просто ссылаться на файлы с помощью обычного относительного URI, не использующего квалификатор, наподобие /images/logo.png и загрузчик ресурсов найдёт их.
Совет. Потенциальная множественность изображений с различными вариантами масштабирования, контраста, языка, и возможное наличие других изображений (наподобие вариантов для разных направлений), имеют важное значение для пакета приложения: большее количество изображений увеличат размер пакета. Более крупный пакет в Магазине Windows может оттолкнуть некоторых пользователей от загрузки вашего приложения, особенно если они пользуются лимитированными сетями. Таким образом, нужно аккуратно оценить реальную необходимость в изображениях, которые позволят обеспечить вариации различных факторов, особенно это касается больших изображений, и оптимизировать уровень сжатия всех изображений для уменьшения размера пакета. Задайтесь вопросом, нужно ли локализовать ваш экран-заставку – обычно одно из самых больших изображений, особенно в масштабе 180%, и проверьте, хорошо ли выглядит изображение, подготовленное для масштаба в 180%, когда оно масштабируется до 140%, до 100%. Если ваш экран-заставка, другими словами – это лишь изображение с достаточным уровнем контрастности и вы используете на нём универсальное имя приложения, один файл можно будет использовать во всех случаях.
Так же обратите внимание, что нет необходимости предоставлять ресурс без квалификатора, если вы предоставляете все остальные специфические варианты, так как масштабированный вариант всегда будет иметь преимущество над обычным. В результате, ресурсы без квалификаторов в именах просто занимают место в пакете приложения, но никогда не используются.
Для подготовки к локализации, нам нужно лишь переместить изображения в папку для нашего языка по умолчанию, как мы поступали и со строками. Так как вы уже используете относительные URI для того, чтобы ссылаться на изображения (с использованием ms-appx:/// или нет), вы можете использовать любой желаемый путь к папке в качестве корневой папки для изображением. Там, создайте папку с именем, соответствующим подходящему тегу языка BCP-47 и переместите все ваши файлы для языка по умолчанию в эту папку. В приложении "Here My Am!", например, изображения находятся в папке images, таким образом, всё, что нужно сделать – это создать папку en-US в данной папке, переместить в нее все изображения, и все мои ссылки вида /images/tile.png будут продолжать работать. И потому что теперь они находятся в папке, которая соответствует языку приложения по умолчанию, они становятся резервными изображениями.
У мня есть одно изображение, maperror.png, которое расположено в папке pages/home вместе с файлом home.html, который на него ссылается. Я переместил это изображение в папку images/en-US и обновил ссылки URI соответствующим образом (но потом отказался и от него, и от taphere.png в пользу динамического рисования в элементе canvas). Вы можете, конечно, разместить изображения в любом желаемом количестве папок, учитывая, что каждая из них имеет внутри себя папки, соответствующие различным языкам. Возможно, это более удобно, однако, использовать одну корневую папку, или лишь несколько. В случае с "Here My Am!", в конце данного шага у меня было две языковых папки в проекте:
В вашем приложении, соответственно, посмотрите на ссылки на изображения в проекте. В HTML обращайте особое внимание на элементы img. В CSS обращайте внимание на стили background-image. В манифесте посмотрите на закладку Интерфейс приложения (Application UI) (логотипы, значки), на закладку Объявления (Declarations) (еще логотипы), и на закладку Упаковка (Packaging) (логотип для Магазина Windows). В JavaScript, наконец, проверьте любые URI, которые вы могли назначить свойствам элементов или CSS-стилям, так же как и те, на которые вы могли ссылаться в XML для плиток, индикаторов событий и всплывающих уведомлений.
После всего этого проверьте каждое изображение для того, чтобы определить, нуждается ли оно в локализации, включая те, которые должны быть реверсированы для использования в языках с письменностью справа налево (для этих целей вы можете использовать по одной копии для всех RTL-языков, назвав их с помощью квалификатора layoutdir qualifier; посмотрите об этом в материале "Как именовать ресурсы, используя квалификаторы" (http://msdn.microsoft.com/library/windows/apps/hh965372.aspx) ). Изображения, не нуждающиеся в локализации (возможно, изображение для плитки, логотипы, простые графические элементы, которые вы используете в макете), держите в папке резервного языка. Они будут использованы, если другие не подойдут под текущий набор квалификаторов (язык, масштаб, контраст и так далее). Полагайтесь на резервные данные, если только у вас нет других вариантов. В итоге, теперь всё готово для локализации!
Пример "Ресурсы приложения и локализация" (http://code.msdn.microsoft.com/windowsapps/Application-resources-and-cd0c6eaa) показывает множество различных сценариев того, как можно управлять локализованными ресурсами и ссылаться на них. Полезно будет потратить некоторое время на работу с этим примером, так как он использует большую часть того, о чем мы здесь говорили: графические ресурсы (Сценарий 1); строковые ресурсы в HTML, JavaScript и в манифесте (Сценарии 2-4); использование дополнительных файлов ресурсов (Сценарий 5); отправка сведений о языке на веб-сервис (Сценарий 7); комбинацию ресурсов и привязки данных (Сценарий 8); использование ресурсов с именами, содержащими дефис ((Сценарий 9); вызов и обработка изменения язка (Сценарии 10 и 6); переназначение языкового контекста по умолчанию (Сценарий11); использование WinJS для разрешения ресурсов в веб-контексте (Сценарий 12); и многомерные резервные данные ((Сценарий 13).
Примите поздравления! Благодаря всему, что мы сделали в предыдущих разделах, мы должны получить приложение, которое полностью готово к локализации. Всё, что нужно теперь сделать – получить переведенные версии ваших файлов .resjson (для строк, примите к сведению возможность разреженной локализации) и переведенные версии любых необходимых изображений.
Совет. Если у вас есть изображения, которые содержат текст, убедитесь, что у в ваших файлах ресурсов есть строки, соответствующие содержимому изображений, так как их обычно используют в качестве атрибутов alt для изображений. Делая это, вы получаете необходимый перевод для изображений в процессе локализации строк.
Если хотите вы можете просто передать ваши файлы .resjson files, вместе с изображениями, содержащими текст, переводчику или в агентство переводов и предоставить им возможность делать свою работу. Когда вы получите материалы обратно, просто создайте дополнительные папки с кодами BCP-47 в ваших папках strings и images, поместите в них данные файлы и всё будет сделано. Вы увидите подобные структуры в примере "Ресурсы приложения и локализация", о котором мы упоминали ранее.
Ручной перевод может занять много времени и немало стоить. Это, от части, потому что профессиональные переводчики не обязательно имеют инструменты для работы с файлами ресурсов, обходясь текстовыми редакторами. Им хорошо было бы иметь современные инструменты, которые помогали бы им отслеживать состояние работы по переводу и много всего еще, работать с индустриальным стандартом в виде формата XML, известным как XLIFF (XML Language Files). В итоге, это обязывает нас (и наши чековые книжки!) упростить жизнь переводчикам, даже уменьшить объем работы, позволив просматривать связанные переводы вместо того, чтобы делать всю работу с нуля.
Для того чтобы в этом помочь, Microsoft предлагает бесплатный инструмент Multilingual App Toolkit (набор средств для многоязыковых приложений) для Visual Studio 2012 (http://msdn.microsoft.com/ru-rU/windows/apps/hh848309.aspx). Как только вы загрузите и установите набор средств, загрузите ваш проект в Visual Studio и выполните команду Сервис>Включить набор многоязычных инструментов (Tools>Enable Multilingual App Toolkit). Вам нужно сделать это для каждого проекта по отдельности, потому что в этот момент набор средств создает многоязычные ресурсы для вашего приложения – в файле resources.pri даже если вы не добавляли дополнительные файлы .resjson.
Как только вы включили набор инструментов, в меню Проект (Project) добавляется команда Добавить языки переводов (Add Translation Languages). Она вызывает диалоговое окно Языки переводов (Translation Languages), как на рис 16.5, в котором вы выбираете желаемые целевые языки. На самом верху списка будет автоматически активирована опция Псевдоязык (qps-ploc) (Pseudo Language); мы будем использовать его в следующем разделе для тестирования локализации. Это то, что обычно делают перед локализацией. Кроме того, отметьте, что многие языки отмечены логотипом "Microsoft Translator", что означает, что перевод для них можно, по большей части, выполнить автоматически, сберегая время переводчиков и ваши деньги.
(рис 16.5) Первое диалоговое окно набора средств для многоязыковых приложений для выбора языков перевода. Слева можно видеть опцию Псевдо-язык (Pseudo Language), искусственный язык с множеством интересных символов, которые представляют нужды большинства других языков
Видео!
Ниже представлены ссылки на видеоматериалы по набору средств для многоязыковых приложений:
Как только вы выбрали нужные языки (вы можете добавить больше позднее), нажмите ОК, и набор средств создаст в вашем проекте папку с именем MultilingualResources, наполненную множеством XLF-файлов (эти файлы любят переводчики). Поначалу они будут практически пустыми, но сейчас вы увидите, для чего было создавать файл ресурсов по умолчанию. Щёлкните правой кнопкой по проекту в Обозревателе решений и выберите команду Построение (Build) или Перестроить (Rebuild), или выполните аналогичную команду меню. Благодаря этой команде будет осуществлен просмотр ваших строковых ресурсов (в том числе – любых локализованных вариантов, которые вы уже создали) и XLF-файлы будут заполнены вашими строками. В ходе этого процесса так же извлекаются ссылки на ваших изображения, не являющиеся логотипами (изображения плиток и экрана-заставки будут опущены), которые так же, возможно, нужно перевести.
Теперь, для настоящего развлечения, сделайте двойной щелчок по XLF-файлу для того, чтобы загрузить Многоязычный редактор (Multilingual App Toolkit Editor), показанный на рис 16.6. Здесь вы можете управлять тем, какие ресурсы можно или нужно переводить, отслеживать состояние перевода. Если язык так же поддерживается системой перевода Microsoft Translator, в верхней части будет активна кнопка Перевести (Translate) для перевода отдельной записи, а так же – Перевести всё (Translate All). Нажмите последнюю кнопку и сидите, наслаждаясь зрелищем. Через некоторое время вы увидите, что набор средств перевел все строки, пометив их все состоянием Требуется проверка (Needs review), как показано на Рис. рис 16.7.
(рис 16.6) Многоязычный редактор (Multilingual App Toolkit Editor), XLF-редактор со встроенным машинным переводчиком
(рис 16.7) Строковые ресурсы приложения "Here My Am!" после машинного перевода на язык хинди
Как только перевод будет завершен, сохраните файл и закройте редактор, если хотите. Перейдите в раздел Панель управления>Часы, язык и регион>Язык (Control Panel>Clock, Language, and Region>Language) и перенесите целевой язык в верхнюю часть списка языков. Теперь вернитесь в Visual Studio и запустите приложение – и перед вами результаты первого этапа локализации, как показано на рис 16.8. для "Here My Am!" (Обратите внимание на то, что я решил не переводить название программы, менять его чем-то, что предложит переводчик, я сохранил его английское написание из-за его уникальной грамматики).
(рис 16.8) "Here My Am!" на хинди, с использованием машинного перевода. Такой перевод, конечно, следует проверить носителю языка. Как видите, я проверяю, есть ли у Йогананды советы относительно языка
Если вы хотите, чтобы ваше приложение обитало на окраинах и не беспокоитесь о том, чтобы отправлять в Магазин Windows приложение, над которым люди на других рынках могут посмеяться или покритиковать вас за небрежность, тогда ничто вас не останавливает от отправки приложения на такие рынки с машинным переводом, подобным этому. Если же вам больше нравятся хорошие оценки и отзывы, тогда полезно будет найти носителей языка, которые смогут проверить и исправить машинный перевод. И эти полезные люди тоже могут использовать Многоязычный редактор для работы с вашими XLF-файлами. Когда эти файлы будут проверены и возвращены к вам, импортируйте их обратно в Visual Studio, щёлкните правой кнопкой по XLF-файлу в Обозревателе проектов и выберите команду Импортировать переводы (Import Translation). Новый перевод будет включен в состав программы при следующем построении.
Работая с профессиональными переводчиками, вы так же можете использовать специальный формат XLIFF Translation, для этого щелкните правой кнопкой мыши по XLF-файлу в Visual Studio и выберите команду Отправить в перевод (Send for Translation).
Вот еще три замечания об этом процессе. Во-первых, могут быть некоторые строки или части строк, которые не нужно переводить. В Многоязычном редакторе вы можете установить параметр Подлежит переводу (Translatable) в значение Нет (No) для всей строки для того, чтобы машинный перевод не изменял её. В случае с частями строк, они будут переводиться, но вы можете отредактировать их, приведя в нужное состояние, после чего, в поле Комментарий (Comments) сделать соответствующую запись для переводчиков.
Во-вторых, набор средств для многоязыковых приложений может определить, что вы уже сделали перевод в XLF-файле, в результате команды построения проекта не переписывают переведенные строки. В то же время, он импортирует любые новые строки, которые вы могли добавить в файл ресурсов и удаляет те, которые были удалены. Изменение в идентификаторе ресурса обрабатывается как удаление и добавление, то есть, перевод строки будет потерян.
И, наконец, если вы хотите удалить язык, просто щёлкните правой кнопкой по XLF-файлу и выберите Исключить из проекта (Exclude From Project). Это исключит файл из построения проекта, но сохранит файл (и переводы) в папке проекта.
Как бы интересен ни был процесс перевода приложения на многие языки, есть и задача всё это как следует протестировать, весьма трудозатратная задача, если вы используете много языков! Для уменьшения этой нагрузки лучший подход заключается в тестировании вашего приложения с использованием Псевдо-языка (Pseudo Language), шаг, который, в идеале, предшествует оценке стоимости перевода. Он поможет вам проверить, верно ли ваше приложение работает с разнообразными языками, так как вымышленный Псевдо-язык содержит некоторые из наиболее проблематичных характеристик локализованного текста.
Как упоминалось в предыдущем разделе, этот язык автоматически добавляется в проект посредством окна выбора языков средства для многоязычных приложений. Создаётся файл Pseudo Language (pseudo).xlf в папке MultilingualResources, рядом с файлами реально используемых языков. После этого нужно щелкнуть данный файл правой кнопкой мыши и выбрать команду Создать псевдопереводы (Generate Pseudo Translations). Эта команда заполнит XLF-файл переводами ваших ресурсов по умолчанию, где обычные символы будут часто конвертированы в расширенные символы и строки обычно завершаются множеством присоединенных "!!!!!", В итоге, строка наподобие "Recent pictures" будет переведена как "[62BD8][!!_????й? ????µ???_!!!!]" где шестнадцатеричный код в первых квадратных скобках [ ] это идентификатор ресурса, который помогает тестировщику определить реальный используемый ресурс. (Обратите внимание, что этот процесс "переведет" каждую строку, независимо от того, будете ли вы переводить эту строку для реальных целей, так как это полезно для тестирования.).
Для того, чтобы запустить приложение с таким переводом, вам нужно сделать Псевдо-язык языком системы по умолчанию. Перейдите в раздел Панель управления>Часы, язык и регион>Язык (Control Panel>Clock, Language, and Region>Language), нажмите на кнопку Добавить язык (Add Language) и введите qps-ploc в поле поиска. Это единственный способ, благодаря которому появится опция Псевдо-язык (Pseudo Language):
Выбрав этот язык, нажмите Добавить (Add) и переместите его в верхнюю часть списка:
Когда вы запустите приложение, вы должны увидеть, что оно отображается с использованием Псевдо-языка:
Когда ваше приложение исполняется с использованием Псевдо-языка, испытайте каждую возможность и опцию. Проверьте каждую страницу в каждом из состояний просмотра; проверитье все команды панели приложения; проверьте все параметры, сообщения об ошибках, всплывающие окна и диалоговые окна сообщений, которые могут появляться лишь при особом стечении обстоятельств наподобие изменения состояния сетевого соединения. И протестируйте все ветви кода активации в соответствии с используемыми им контрактами. Когда вы сделаете это, посмотрите все строки, которые не отображаются на псевдо-языке, что ясно указывает на то, что вы упустили эти строки в коде или разметке и они локализованы не будут. Кроме того, проверьте обрезанный текст, неожиданные переносы слов и так далее, что позволит понять, где ваш макет не способен нормально разместить переведенные строки.
Это время, когда вы должны быть внимательны, как никогда, так как, как только вы отправите приложение в Магазин Windows, выпуск следующего обновления займёт неделю-две, а в течение этого времени ваши пользователи могут обнаружить эти проблемы, что соответствующим образом отразится на рейтинге вашего приложения. Об этом всегда стоит помнить, особенно, если вы привыкли к мгновенному исправлению ошибок на веб-сайтах: для приложений требуется больше времени, поэтому лучше потратить больше времени на тестирование.
Итак, мы почти завершили работу над приложением и готовы отправляться в Магазин Windows! Осталось лишь упомянуть еще кое-о чем, касающемся локализации:
WinJS.Resources.addEventListener("contextchanged", function () { WinJS.Resources.processAll();
});
Мы прибыли в последний раздел данной лекции и последний раздел курса, совершив полный круг. Пришло время отправки вашего приложения, готового к мировому рынку, в Магазин Windows для того, чтобы сделать его доступным для мира.
Так как процесс отправки приложения хорошо документирован в материале "Продажа приложений" (http://msdn.microsoft.com/library/windows/apps/br230836), я не собираюсь тратить наше время, показывая вам кучу скриншотов Информационной панели (https://appdev.microsoft.com/StorePortals), где всё это выполняется. Я укажу вам на конкретные страницы соответствующих документов, если будет нужно, но это будут разделы документации, которые вам нужно будет просмотреть. В конце концов, Магазин Windows – это канал продажи для ваших приложений, в итоге, вам нужно будет понять этот канал так хорошо, как только возможно. Информационная панель Магазина Windows, кроме того, создана для того, чтобы провести вас через все этапы данного процесса.
То, на чем мы здесь сконцентрируемся, это те аспекты процесса, которые не всегда очевидны, основываясь на реальном опыте, который я и мои сослуживцы получили в Windows Ecosystem Team в ходе работы с первыми партнерами над отправкой приложений в Магазин Windows. Посредством этого я надеюсь повысить ваши знания о возможных проблемах, с которыми вы можете столкнуться, в итоге, вы лучше будете подготовлены к ним. Затем мы поговорим об обновлениях приложения и об увеличении вероятности обнаружения вашего приложения пользователями благодаря его связью с вашим веб-сайтом.
Когда вы создаете пакет вашего приложения для загрузки его в Магазин Windows, не забудьте установить конфигурацию приложения в значение Выпуск (Release) вместо значения Отладка (Debug), иначе оно не пройдёт сертификацию. Выбирая целевую платформу, установите её в значение "Any CPU", если только у вас нет WinRT-компонентов, написанных на C++. Таким образом, JavaScript и .NET-языки (C#/VisualBasic) архитектурно-нейтральны. С другой стороны, всё, аписанное на C++, должно компилироваться под конкретную платформу: x86, x64,и ARM. Чаще всего вам придется создавать три варианта построения для этих архитектур, которые вы будете загружать в Магазин Windows отдельно.
Прежде чем вы сделаете что-то еще, связанное с вашим приложением и Магазином Windows, посмотрите материал "Представление приложения в Магазине Windows" (http://msdn.microsoft.com/library/windows/apps/hh694057.aspx) и дополнительные материалы: "Информация об описании приложения" (http://msdn.microsoft.com/library/windows/apps/hh694060.aspx), "Выбор изображений для вашего приложения" (http://msdn.microsoft.com/library/windows/apps/hh846296.aspx). Кроме того, обратитесь к материалу "Подготовка приложения для отправки в Магазин Windows" (http://msdn.microsoft.com/library/windows/apps/hh694079.aspx), который предоставляет множество ценных сведений о процессах, которые предшествуют отправке приложения, в частности, он содержит ссылки на такие материалы, как "Выбор названия приложения" (http://msdn.microsoft.com/library/windows/apps/hh694079.aspx) и "Что необходимо включить в описание приложения" (http://msdn.microsoft.com/ru-RU/library/windows/apps/hh694076.aspx).
Причина, по которой я указываю эти материалы, заключается в том, что вы уже потратили, или собираетесь потратить много времени и сил на разработку приложения (и на тестирование, как мы обсудим в следующем разделе), и вы должны приложить сравнимые усилия для того, чтобы ваше приложение отлично выглядело в Магазине Windows. Всё то, о чем говорится в вышеупомянутых материалах: название и описание приложения, подробности о приложении, рекламные изображения – всё это составляет первое впечатление пользователей от вашего приложения.
Позвольте мне повторить снова: всю эту информацию потенциальный покупатель будет использовать для оценки вашего приложения до того, как он нажмёт кнопку для того, чтобы получить это приложение. Это маркетинговые материалы, простые и понятные, поэтому пусть они будут просто великолепными! Потратьте некоторое время на написание по-настоящему хорошего текста описания приложения – можете даже передать их профессиональному редактору или нанять профессионального технического писателя. Если вы чувствуете, что ваше приложение забавное и увлекательное, расскажите об этом через тексты и изображения. На самом деле, вы ведь хотите, чтобы первое впечатление пользователя о вашем приложении – после взгляда на страницу приложения – было бы в стиле "Ух ты!". И именно вышеупомянутое содержимое определяет подобную реакцию.
Другая причина, по которой я так настойчиво это выделяю заключается в том, что иначе вы просто не узнаете о том, что вам всё это нужно, до процесса отправки, когда Магазин Windows запросит у вас текст и изображения. Если вы еще не подготовили эти материалы, таким образом, и вы пытаетесь отправить приложение в Магазин Windows так быстро, как только можно, вы, в итоге, столкнетесь с весьма серьезными неприятностями. В результате, первое впечатление от вашего приложения будет далёко не таким хорошим, каким оно могло бы быть.
Сертификат с оценкой игры. Отправляя в Магазин Windows игру, вы должны получить сертификат с оценкой игры в форме GDF-файла. Для того чтобы узнать подробности, смотрите материал "Требования к публикации игр в Windows" (http://msdn.microsoft.com/library/windows/apps/hh452788.aspx).
Если только вы не рождены тестером, тестирование приложения подразумевает меньше сильных впечатлений, чем разработка, однако, оно может сыграть ключевую роль в успехе вашего приложения.
На самом деле, для многих разработчиков, особенно тех, которые сконцентрированы на веб, как я ожидаю, и для мноогих читателей, строгое тестирование не является одним из их ключевых занятий. Я думаю так из-за природы веб-разработки, когда вы можете загрузить на сайт исправление, которое мгновенно возымеет действие, что не требует особой дисциплины в тестировании. Часто ли вы видите, как ваши любимые веб-сайты просто не доступны весь день, или плохо работают несколько часов, а затем снова возвращаются к жизни? Это, возможно, потому что какой-нибудь разработчик допустил неприятную ошибку, которая была обнаружена и исправлена в течение этих часов. Для некоторых сайтов это подобно катастрофе, но для многих других это нежелательно, хотя и не смертельно.
Говоря другими словами, стоимость ошибок в веб-приложениях обычно очень мала, так как время обновления так же очень мало. Но это не так для приложений. Время с момента, когда вы отправляете приложение в Магазин Windows, до того момента, когда оно будет доступно потребителям, это, как минимум, неделя, если не больше, в зависимости от загруженности Магазина Windows. Это означает, что каждая отправка весьма важна.
Посмотрим на это с точки зрения затраченного времени. Скажем, для того, чтобы загрузить исправление для веб-приложения, нужно пять минут. Сравните это с количеством минут в неделе, которых в ней 10800. Каково соотношение? 1 к 2016. Другими словами, это, как минимум в 2000 раз дороже с точки зрения времени и усилий, потраченных на обновление приложения в Магазине Windows. Говоря с практической точки зрения, это значит, что вам придется потратить гораздо больше усилий на тестирование приложений, чем на тестирование веб-сайтов. И не так уж и мало! (И не возражайте, говоря, что вы тратите нулевое время на тестирование веб-приложений, а значит и цена обновления при таком подходе так же равна нулю)
Если у вас нет методологии тестирования, тогда начните её создавать, даже с нуля. Например, не забудьте всегда тестировать ваше приложение на чистой установке Windows 8, на компьютере без лицензии разработчика, а так же на маломощных компьютерах, производительность которых похожа на производительность многих ARM-устройств. У одного из разработчиков, с которым я работал, было приложение, которое было отвергнуто Магазином Windows, так как оно просто было пустым при первом запуске – он никогда не видел, как это происходит из-за кэшированных данных, которые были на его компьютере!
Вам так же нужно построить хороший список того, что нужно делать с вашим приложением, чтобы исполнить все ветви его кода. Это должно включать и учет тех условий, которые являются внешними по отношению к приложению: изменение режимов просмотра и ориентации устройства; активация различных чудо-кнопок; изменение состояния соединения с сетью; работа с медленными каналами передачи данных; удаление временных файлов приложения с помощью средства очистки диска; вход с различными учетными записями; приостановка, возобновление работы и запуск после остановки; работа в высококонтрастных режимах и с другими специальными возможностями; работа в системах с разными языками. Чем лучше ваше приложение ведет себя во всех этих условиях, тем более целостным будут видеть его пользователи, которые пишут отзывы и ставят оценки. Я рассказал об этом в видео, которое называется "Beyond Just Beautiful", которое вы можете найти на странице "Принципы работы и архитектура" (http://msdn.microsoft.com/library/windows/apps/br211361.aspx) в Центре разработчиков.
Помимо этого есть некоторые отличные материалы в документации, которые помогут вам выполнить данные шаги:
Другая очень важная часть тестирования – это испытание приолжения с помощью Комплекта сертификации приложений для Windows (Windows App Certification Kit, WACK). Данный инструмент подвергает ваше приложение всем автоматизированным тестам, которые оно проходит после отправки в Магазин Windows, таким образом, позволяя вам исправить найденные проблемы. Прохождение тестов WACK не гарантирует, что ваше приложение будет принято, но, определенно, сохраняет вам много времени на ожидание результатов отправки и избавляет от необходимости повторно отправлять приложение снова и снова. Вам следует, на самом деле, запускать WACK практически ежедневно в процессе разработки. Вам не обязательно исправлять всё, что он обнаружит, сразу же, но текущие данные будут весьма полезными.
Для того, чтобы узнать подробности об этом инструменте и о работе с ним, смотрите материал "Тестирование приложения с помощью комплекта сертификации приложений для Windows" (http://msdn.microsoft.com/library/windows/apps/hh694081.aspx) и "Тестирование приложений с помощью комплекта сертификации приложений для Windows" (http://msdn.microsoft.com/library/windows/apps/jj657973.aspx).
Совет. Если вы обнаружили, что WACK не отображает приложения для тестирования, попытайтесь деинсталлировать примеры SDK, которые вы могли запускать из Visual Studio. Такое ощущение, что иногда этот инструмент испытывает перегрузки.
Когда вы готовы к отправке приложения в Магазин Windows, вы можете использовать меню Visual Studio Магазин (Store). Команда Создать пакеты приложения (Create App Package) позволит вам создать пакет, готовый для отправки в Магазин Windows (и для запуска в WACK). Команда Отправить пакеты приложения (Upload App Package) перенаправит вас в Информационную панель Магазина Windows для того, чтобы завершить этот процесс. И, если вам интересно, максимальный размер приложения для загрузки – 2 Гб (смотрите материал "Сборка пакета приложения" (http://msdn.microsoft.com/library/windows/apps/hh694075.aspx).
В процессе отправки приложения у вас запросят все рекламные материалы и сведения, которые мы обсудили выше, а так же URI технической поддержки и страницы с соглашением о конфиденциальности. Так же вы можете выбрать целевые рынки, установить цены, ввести подробности по покупкам из приложения, задать время действия пробного периода, задать дату выпуска, и предоставить примечания для тестировщиков Магазина Windows. (Обзор этого процесса представлен в материале "Контрольный список для подачи приложения" (http://msdn.microsoft.com/library/windows/apps/hh694062.aspx). Последнее очень важно, если что-либо может быть важным для реально существующего человека, который будет тестировать ваше приложение, например, учетные данные для тестовой учетной записи. И, да, реальные люди будут смотреть на ваше приложение (и читать ваши примечания, поэтому будьте вежливы)! Автоматизированные тесты могут сделать довольно много, но в конце кто-то должен запустить приложение и взглянуть на всё своими глазами.
Если вы проделали большую работу для того, чтобы обеспечить доступность приложения, кстати, есть специальное место для того, чтобы это указать. Смотрите материал "Объявление о специальных возможностях вашего приложения в Магазине Windows" (http://msdn.microsoft.com/library/windows/apps/Hh700322.aspx).
Как только ваше приложение пройдёт процесс тестирования, оно будет либо принято, либо отвергнуто. Принятие – это не проблема – это то, чего вы и ожидаете. А если ваше приложение не принято, с другой стороны, из Магазина Windows вам сообщать, почему, перечислив нарушения правил сертификации приложений для Windows 8. На самом деле, эти правила содержат причины, по которым приложение может быть не принято, поэтому каждый отказ в публикации должен содержать конкретное требование, которое не было удовлетворено. Магазин Windows так же предоставляет некоторые сведения об ошибках, о том, где именно приложение аварийно завершило работу (нарушение пункта требований 1.2.)
По большому счету, большая часть правил достаточно проста, поэтому если вы их нарушили, довольно понятно, почему это так. Некоторые, однако, выглядят запутаннее и субъективнее, и в первые дни существования предварительного релиза Windows 8 они были просто загадочными. Сейчас, к счастью, составлен обширный список причин того, почему приложение может нарушить эти правила, он содержится в материале "Устранение ошибок сертификации" (http://msdn.microsoft.com/library/windows/apps/hh921583.aspx), многие из этих ошибок пришли из опыта работы с реальными приложениями, отправленными в Магазин Windows. Тестировщики Магазина Windows так же могут предоставлять непосредственные отзывы относительно специфических ошибок, наподобие того, где и когда приложение может аварийно завершиться, что, конечно, принуждает их отказывать в сертификации.
У книг и приложений есть общая черта, когда в момент их выпуска вы находите ошибки, нестыковки, опечатки и сотни других вещей, которые вам хочется исправить. К счастью, обновить приложение легче, чем обновить книгу (даже несмотря на то, что исправить ошибку в приложении часто сложнее, чем исправить опечатку).
Вы можете решить выпустить обновление по многим причинам, помимо исправления очевидных проблем, которые вы увидели сами и реализации возможностей, которых нет в текущей версии. Вам может захотеться ответить на обзоры и вопросы пользователей, добавить больше продуктов для покупки из приложения, или добавить функции для достижения новых возможностей. Для почти всех этих целей, отчеты и данные (http://msdn.microsoft.com/library/windows/apps/jj193602.aspx), поступающие из Магазина Windows могут быть весьма ценными. Вы будете просматривать их как только ваше приложение окажется в Магазине Windows и лучше всего составить план по мониторингу наиболее интересных для вас отчетов.
Некоторые соображения по этому поводу можно найти в материале "Обновление вашего приложения для Магазина Windows" (http://msdn.microsoft.com/library/windows/apps/jj606115.aspx). На самом деле, запланируйте некоторое время в будущем прямо сейчас для того, чтобы проверять эти отчеты, чтобы не забыть об их существовании. И данные отчеты, действительно, это лучший способ связи с реальными пользователями.
Все подобные данные, конечно, попадают в ваши процессы планирования и разработки, в конечно мсчете, приводя вас к моменту загрузки вашего приложения с новыми рекламными материалами и новыми функциями. Когда вы готовы к загрузке нового пакета, не забудьте увеличить номер версии в манифесте, чтобы вы могли это учитывать. (Эти сведения доступны во время выполнения из Windows.ApplicationModel.Package.current.id.version (http://msdn.microsoft.com/library/windows/apps/windows.applicationmodel.packageid.version.aspx) ). Процесс отправки не отличается от отправки любого другого приложения – не важно, как малы изменения, приложение снова пройдёт полный процесс сертификации. По этой причине не планируйте мелких изменений – сделайте каждое из них значительным (исправка одной критической ошибки, безусловно, имеет значение)! Кроме того, знайте, что сертификационные требования могут время от времени изменяться, поэтому, если приложение однажды уже прошло сертификацию, это не означает, что оно снова её пройдёт. Возьмите себе за правило периодически пересматривать требования.
В обновленном приложении будьте готовы выполнить миграцию состояний, которые могут уже присутствовать на компьютере, если они меняются. Об этом вы можете посмотреть в Главе 2 курса "Пользовательский интерфейс приложений для Windows 8, созданных с использованием HTML, CSS и JavaScript", где говорится о разнице между версиями приложений и версиями их состояний; множество версий приложения может использовать ту же самую версию состояния приложения. Однако, если приложение теперь использует новую версию состояния, старая версия должна мигрировать. Помните так же, что вы можете использовать для этого фоновую задачу servicingComplete, об этом говориться в Главе 2. И, наконец, как только вы представили новую версию состояния приложения, перемещаемые данные будут перемещаться между приложениями, работающими с одной и той же версией состояния – вы можете произвести миграцию старых состояний, когда новое приложение запущено, но как только версия будет увеличена, данные больше не будут перемещаться на устройства с более старой версией приложения.
Последнее, что стоит сказать об обновлениях, это то, что хотя новый пакет приложения может быть достаточно велик, существующим пользователям не придется загружать всё. Пакет приложения разбит на блоки размером по 64 Кб, и лишь те блоки, которые изменились между версиями необходимо загрузить для выполнения обновления. С практической точки зрения это означает, что вам не следует беспокоиться при создании критических обновлений к приложениям: они затронут только небольшую часть кода, и существующие пользователи приложения, в итоге, вполне могут загрузить лишь один блок размером в 64 Кб! Для того, чтобы этому помочь, постарайтесь, чтобы в вашем проекте лучше было бы больше файлов маленького размера, нежели несколько больших, и лучше вносить изменения в конце файлов, чем в начале или в середине.
Гэндальф Серый сказал Фродо, Сэму, Мерри и Пиппину в завершении фильма "Властелин колец": "Мой труд завершён. Здесь, на берегу моря, нашему братству приходит конец". И, мои друзья, я был счастлив совершить это путешествие вместе с вами! В этом последнем разделе я хочу рассказать вам об одном техническом вопросе – о связи приложения с вашим веб-сайтом – прежде чем поделюсь некоторыми итоговыми мыслями.
Если у вас есть приложение, то почти наверняка у вас есть сайт, который предоставляет дополнительную информацию и поддержку (пункт 6.3. требований посвящен технической поддержке). Что, если потенциальный покупатель сначала попал на ваш сайт? Очевидно, вы хотели бы предоставить ему простой способ для получения вашего приложения, если он работает на Windows 8.
Для того, чтобы это сделать, вы можете просто предоставить ему ссылку на специальный URI, ведущий в Магазин Windows, начинающийся с ms-windows-store, как описано в материале "Ссылки на приложение" (http://msdn.microsoft.com/library/windows/apps/hh974767.aspx). Вы можете использовать форму ms-windows-store:REVIEW? для создания ссылки, ведущей непосредственно к оценкам и отзывам о вашем приложении. И, кроме того, помните, что вы можете включить ссылку на страницу вашего приложения в Магазине Windows в пакеты с данными, которые вы предоставляете для контракта Общий доступ, об этом можно узнать в Главе 1.
С помощью Internet Explorer, немного метаданных в теге <head>
вашей веб-страницы упростят пользователю получение вашего приложения и даже его запуск после установки приложения. Например:
<meta name="msApplication-ID"
content="ProgrammingWin8-JS-CH17-HereMyAm17"/>
<meta name="msApplication-PackageFamilyName"
content="ProgrammingWin8-JS-CH17-HereMyAm17_5xchamk3agtd6"/>
Здесь два значения content берутся из полей Имя пакета (Package Name) и Имя семейства пакетов (Package Family Name) на закладке Упаковка (Packaging) редактора манифеста. Если у пользователя нет вашего приложения, это упрощает процесс его получения. Если у пользователя уже есть приложение, у него появляется возможность запустить его, в таком случае приложение будет активировано с видом активации protocol.
Для того, чтобы узнать больше, посмотрите материал "Связывание приложений с ресурсами в Интернете" (http://blogs.msdn.com/b/windowsstore_ru/archive/2012/02/29/linking-to-your-apps.aspx) в блоге для разработчиков Магазина Windows и материал "Связывание вашего веб-сайта с вашим приложением для Windows 8" (http://blogs.msdn.com/b/ie/archive/2011/10/20/connect-your-web-site-to-your-windows-8-app.aspx) в блоге Interner Explorer). И, для того, чтобы увидеть рабочий пример, посетите сайт Inrix Traffic (http://www.inrixtraffic.com/), одного из первых партнёров, который реализовал эту функцию.
Еще одна возможность продвижения приложения, которая приходит здесь в голову: OEM-производителя может заинтересовать ваше приложение для предустановки на их устройства. Если это произойдёт – это настоящий подарок! – тогда OEM-производитель предоставит вам некоторые специальные инструкции о том, как подготовить приложение специально для его клиентов.
Само собой разумеется то, что Магазин Windows будет в какой-то момент содержать огромное количество приложений, в итоге, очень важно будет дифференцировать себя, как разработчика, и своё приложение. Опять же, здесь можно много говорить о маркетинге и приобретении известности вашим приложением, так же, как и о реагировании на нужды клиентов. Помимо этого, однако, что делает приложение по-настоящему особенным?
Ранее, задолго до того, как Microsoft стала использовать термин "Приложения для Магазина Windows", мы называли их "tailored apps" ("индивидуальные", "сшитые на заказ", "подогнанные"). Поэкспериментируем с этим старым термином, подумаем о том, что "подгонка" означает в контексте одежды: хорошо сшитая одежда весьма заметна. Она позволяет вам выглядеть по-настооящему хорошо. Она позволяет вам хорошо себя чувствовать. Это именно то, что должен чувствовать пользователь вашего приложения, когда он погружается во взаимодействие с ним. На самом деле, так же, как вы получаете море удовольствия и счастья от процесса разработки, пусть то же самое испытывают и пользователи ваших приложений. Если вы можете принести им радость с помощью вашего приложения, тогда, я думаю, вы добились этой цели!
Другое значение слова "tailored" подразумевает, что те программы, которыми мы здесь занимаемся – это приложения, которые запускаются на полном экране и полностью погружают пользователя в работу с ними, позволяют такому взаимодействию распространяться и на устройство, и на контекст пользователя. Датчики, речь о которых идет в Главе 3 курса "Пользовательский интерфейс приложений для Windows 8, созданных с использованием HTML, CSS и JavaScript", дают вам возможность знать о взаимоотношениях устройства с физическим миром, который является продолжением пользователя, который держит устройство. Спросите тогда: "Что я могу делать с подобной информацией? Как может вести себя приложение, когда у него есть более глубокое понимание того, где находится пользователь, как он перемещается? Если что-то большее, что может сделать приложение, чем спросить: "Рады ли вы, что взяли меня с собой?".
Для того, чтобы выделить ваше приложение, подумайте о том. как пользователь может использовать устройства разных форм-факторов в разных ситуациях, и выглядит ли приложение по-разному в разных ситуациях. Подобный вид персонализации подразумевает то, что приложение содержит наиболее подходящие возможности или содержимое для наиболее вероятных или подходящих вариантов использования. В соответствии с нижеприведенным рисунком, мне нравится думать о том, что одно и то же приложение может существовать на разных устройствах, и что у пользователя имеется более сильная связь именно с приложением, а не с устройством, на котором оно работает.
Чтение журналов, пометка интересных рецептов (Read magazines, mark recipes of interest)
Планирование меню с отмеченными рецептами, составление списка покупок (Plan menus with marked recipes, make shopping lists)
Просмотр списка покупок, поиск магазинов с лучшими ценами (И, да, здесь у Microsoft есть история с телефонами…) (See shopping lists, locate stores with best prices (And yes, Microsoft will eventually have a story with the phones here…))
Подготовка дневного рациона в соответствии с планом меню (а это – планшет, который можно мыть в посудомоечной машине!) (Prepare the day’s meals according to menu plan (this is a dishwasher-safe tablet too!))
Варианты использования приложения для планирования рациона
Приложение и лежащие в его основе возможности действуют последовательно, во всём диапазоне возможных ситуаций работы с приложением, когда устройство – это лишь транспортное средство. Чем больше ваше приложение соответствует этому и поддерживает это (очевидно, перемещаемые данные здесь очень важны), тем больше, мне кажется, приложение отличается в лучшую сторону от других приложений, которые, конечно, работают в новом окружении Windows, но предлагают те же модели использования, которые существуют уже многие годы
Так как же приложению стать звездой? Давайте будем честными. Вы в этой игре ради имени и славы, верно? И ради больших денег, которые с ними приходят? Какое приложение может дать вам всё это?
Итак, вот последний абзац (если не считать сводки в конце лекции). Я не могу, на самом деле, дать вам кучу конкретных идей (иначе я писал бы эти программы вместо того, чтобы писать книги, но кто-то должен делать и эту работу…). Но задумайтесь над этим: что способствует появлению рок-звезды в музыкальной индустрии? Обычно это не философская глубина лирики или виртуозное исполнение. Это – шоу, личность, ценность зрелищных мероприятий, полных счастья. Это – радость, которая превращает обычных людей в безумных фанатов, которые жаждут быть вашими горячими сторонниками. На самом деле, впечатления – это то, что позволяет людям сбежать из их повседневной реальности и стать частью чего-то большего на какое-то время, или даже частью фантазии. И, как в случае с великой музыкой или великими фильмами, позитивные впечатления от приложения, это то, что людям хочется повторять снова и снова, а не просто ставить галочку, как другие "был там, сделал это". Хотя это, конечно, вопросы времени и счастливой случайности, но все рок-звезды, вместе с великими спортсменами, фильмами, получившими Оскар, вроде "Властелина колец", и так далее, стремились, прежде всего, лишь к одному: к совершенству. Посвятите себя этому. Посвятите себя совершенству во всём, что вы делаете – не только в разработке приложений, но и во всех сферах собственной жизни. Подобное стремление, несомненно, принесет вам множество потрясающих результатов!
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.