Всегда хочется верить в то, что создаваемый Вами программный продукт выйдет за пределы своей страны. Это с одной стороны. С другой стороны, количество возникающих по этой причине сложностей будет очень велико. В этом посте я постараюсь раскрыть некоторые из них.
Давайте для начала рассмотрим сложность интернационализации. Условно, у нас есть программа, которая написана в России и имеет русский интерфейс, поэтому ее нужно будет перевести на любой другой язык, к примеру, на французский.
Почему в примере именно французский? А очень просто — в нем есть такая вещь, как диакритические знаки, поэтому придется использовать Unicode и не удастся обойтись только английской раскладкой ;)
Итак, что же нам надо перевести?
0. А в чем, собственно, проблема?
Давайте для начала рассмотрим сложность интернационализации. Условно, у нас есть программа, которая написана в России и имеет русский интерфейс, поэтому ее нужно будет перевести на любой другой язык, к примеру, на французский.
Почему в примере именно французский? А очень просто — в нем есть такая вещь, как диакритические знаки, поэтому придется использовать Unicode и не удастся обойтись только английской раскладкой ;)
Итак, что же нам надо перевести?
- интерфейс приложения
инсталлятор (если таковой есть)
Разумеется, современная тенденция такова, что инсталлятор часто можно не использовать, однако, я всегда считаю его удобной вещью для отображения лицензионного соглашения (это также отлично согласуется с законодательством России). Мы же ведь не можем выпускать свой продукт во внешний мир без правил, не так ли?
Подходим к проблеме. Держать раздельные версии приложения на разных языках будет не очень удобно. Представьте себе, какой объем изменений нужно будет вносить при правках кода, а также помните, что выдавать переводчику исходный код будет тоже не очень правильно. Поэтому исходный код у нас должен быть один.
Еще один способ — файлы ресурсов, то есть, когда в приложение (либо в исполняемый файл, либо в библиотеку) «вшит» какой-либо язык. Возникает вопрос — как его опознать и выбрать.
1. Подходящее решение
Когда эта проблема встала передо мной, то я выбрал себе следующие правила интернационализации:
1. Инсталлятор должен позволять выбрать язык инсталлятора пользователю, при этом окно инсталлятора с приглашением выбрать язык выбирает его исходя из языковой версии операционной системы, а также именно на этом языке создаются все ярлыки
2. Язык приложения выбирается отдельно на одном из этапов инсталлятора
3. Пользователь должен выбрать, поддержка каких языков ему нужна в приложении
4. После установки приложения должна быть возможность выбрать другой язык его интерфейса
2. Как делать будем?
Вопрос выбора инсталлятора заслуживает отдельного и масштабного обсуждения, но я использую NSIS. Поэтому выполнение первых трех пунктов удалось без проблем — мультиязыковая поддержка в NSIS есть изначально, я только немного поправил языковые файлы.
Далее следует рассказать, каким путем я пошел с языковыми файлами. На мой взгляд, элегантным решением было взять по *.xml файлу для каждого языка, храня в нем все нужные строки. В сам исполняемый файл я «зашил» только английский язык, на случай, если пользователь возьмет и удалит все языковые файлы от злости.
XML мне удобен также потому, что я могу быстро проверить файл на корректность по схеме, то есть, если пользователь сам правил языковой файл и ошибся, программа его не загрузит.
XML вполне нормально поддерживает Unicode, это также было большим плюсом.
3. Что получилось в итоге?
В итоге, решение выглядит так — в папке программы после установки есть папка language. В ней хранятся языковые файлы под именами ru.xml, en-GB.xml, en-US.xml и так далее. Набор языковых файлов определяется пользователем при установке.
в папке с программой находится файл language.xml, который содержит данные для выбранного пользователем языка. Утилита выбора языка копирует XML файл из папки language в корневую папку программы, определяя тем самым язык.
4. Осложнения
Веб-сервер
Все было бы хорошо, если не одно «но» — у меня в программе один из компонентов содержал самописный Веб-сервер, предназначенный для более удобной отладки. Никакого активного содержимого он не предлагал, просто формировал отладочные данные. Однако, среди них была дата…
В чем проблема с датой? В общем виде — ни в чем. Когда пользователь осуществляет запрос, я вытаскивал из HTTP-запроса поле Accept-Language и всегда точно знал, какой язык выдать. Но, превращение даты в строку исполняется на стороне сервера. Поэтому, чтобы все работало корректно, нужно сменить язык потока обработки на тот язык, который просит браузер пользователя.
Тогда все будет совсем корректно.
Ну и конечно, ресурсы Веб-сервера я хранил в отдельных папках с именами «ru», «en-GB» и так далее. Если язык, который попросил пользователь, там не нашелся, то тогда я выдавал стандартный файл на английском из ресурсов.
Длина слов (строк)
Разумеется, что одни и те же слова в разных языках — разные. Поэтому, создавая интерфейс приложения стоит помнить об этом. Хорошим примером может послужить английское «Unlock» и украинское «Розблокувати».
Разница в цифрах
Помните о том, что если в русском языке разделителем целой и дробной части числа является запятая, то в английском, к примеру, точка. А запятая применяется для разделения тысяч, то есть запись на русском «1 000 000,00» на английском должна выглядеть вот так «1,000,000.00».
Разница в датах
Несмотря на то, что ISO устанавливает формат хранения даты (YYYY-MM-DD), не всегда все так просто и радостно. В России его можно писать как DD-MM-YYYY, но в США — MM-DD-YYYY.
Общим советом по поводу цифр и дат будет форматировать их исходя из языка пользователя и ни в коем случае не «зашивать» в программу самопальный механизм их обработки.
С любовью,
maniaque