Вопросы проектирования для интернационализации

Я прочитал статью Джоуля о Unicode, и я чувствую, что у меня есть хотя бы базовое понимание интернационализации с точки зрения набора символов. В дополнение к чтению этого вопроса , я также сделал некоторые из моих собственных исследований по интернационализации в отношении соображений дизайна, но я не могу не подозревать, что есть намного больше, что я просто не знаю или не «Не знаю, спросить.

Некоторые из вещей, которые я узнал:

  • Некоторые языки читаются справа налево, а не слева направо.
  • Календарь, даты, время, валюта и номера отображаются иначе, чем язык.
  • Дизайн должен быть достаточно гибким, чтобы приспособить намного больше текста, потому что некоторые языки гораздо более многословны, чем другие.
  • Не принимайте значки или цвета как должное, когда речь заходит о семантическом значении, поскольку это может варьироваться от культуры к культуре.
  • Географическая номенклатура варьируется от языка к языку.

Где я нахожусь:

  • Мой дизайн достаточно гибкий, чтобы разместить намного больше текста.
  • Я автоматически переводю каждую строку, включая сообщения об ошибках и диалоговые окна справки.
  • Я еще не пришел к моменту, когда мне нужно было отображать единицы времени, валюты или числа, но я скоро буду там и вам нужно будет разработать решение.
  • Я использую набор символов UTF-8 по всем направлениям.
  • Мои меню и различные списки в приложении отсортированы в алфавитном порядке для каждого языка для упрощения чтения.
  • У меня есть тег парсер, который извлекает теги, отфильтровывая стоп-слова. Список стоп-слов зависит от языка и может быть заменен.

Что я хотел бы узнать больше о:

  • Я разрабатываю загружаемое веб-приложение PHP, поэтому любые конкретные рекомендации в отношении PHP будут очень благодарны. Я разработал свои собственные рамки и в настоящее время не заинтересован в использовании других фреймворков.
  • Я очень мало знаю о незападных языках. Существуют ли конкретные соображения, которые необходимо учитывать, о которых я не упомянул выше? Кроме того, как функции сортировки массива PHP обрабатывают незападные символы?
  • Есть ли какие-то конкретные проблемы, которые вы испытали на практике? Я смотрю как с графическим интерфейсом, так и с кодом приложения.
  • Какие-либо конкретные рекомендации по работе с дисплеями даты и времени? Есть ли разбивка по регионам или языкам?
  • Я видел много проектов и сайтов, позволяя их сообществам предоставлять перевод для своих приложений и контента. Вы рекомендуете это и какие хорошие стратегии для обеспечения хорошего перевода?
  • Этот вопрос в основном зависит от того, что я знаю о интернационализации. Что я не знаю, что я не знаю, что я должен изучить дальше?

Редактировать : я добавил щедрость, потому что мне хотелось бы получить больше реальных примеров из опыта.

Наша игра Gemsweeper переведена на 8 разных языков. Некоторые вещи, которые я узнал в ходе этого процесса:

  • Если переводчику даны отдельные предложения для перевода, убедитесь, что он знает о контексте, в котором используется каждое предложение. В противном случае он мог бы предоставить один возможный перевод, но не тот, который вы имели в виду. Инструменты, такие как Babelfish, переводят, не понимая контекста, поэтому результат обычно бывает таким плохим. Просто попробуйте перевести любой нетривиальный текст с английского на немецкий и обратно, и вы поймете, что я имею в виду.

  • Предложения, которые должны быть переведены, не должны разбиваться на разные части по той же причине. Это потому, что вам нужно поддерживать контекст (см. Предыдущую точку) и потому, что некоторые языки могут иметь переменные в начале или в конце предложения. Вместо того, чтобы сломать предложение, используйте заполнители. Например, вместо

«Это шаг» нашего 15-шагового учебника »,

Напишите что-то вроде:

«Это шаг% 1 нашего 15-шагового учебника»,

и программно замените местозаполнитель.

  • Не ожидайте, что переводчик будет забавным или креативным. Обычно он недостаточно мотивирован, чтобы сделать это, если вы не назовете конкретные текстовые отрывки и не заплатите ему дополнительно. Например, если у вас есть и слово шутки в ваших языковых активах, расскажите переводчику в примечании, чтобы он не пытался их перевести, но вместо этого вместо этого заменил их более мрачным предложением. В противном случае переводчик, вероятно, переводит слово шутки по слову, что обычно приводит к полному бессмыслию. В нашем случае у нас был один переводчик и один писатель-шутка для самого важного перевода (английский).

  • Попробуйте найти переводчика, первым языком которого является язык, на котором он собирается перевести ваше программное обеспечение, а не наоборот. В противном случае он, скорее всего, напишет текст, который может быть правильным, но звучит странно или старомодно для носителей языка. Кроме того, он должен жить в стране, на которую вы нацеливаете свой перевод. Например, немецкий переводчик из Швейцарии не будет хорошим выбором для перевода на немецкий язык.

  • Если это возможно, попросите одного из ваших публичных пользователей бета-тестирования, который понимает конкретный перевод, проверяет переведенные активы и заполненное программное обеспечение. У нас были очень хорошие и очень плохие переводы, в зависимости от того, кто его предоставил. По словам некоторых наших пользователей, шведский перевод был полным тарабарщиной, но было слишком поздно что-то делать с этим.

  • Имейте в виду, что для каждой обновленной версии с новыми функциями вам придется переводить свои языки. Это может создать серьезные накладные расходы.

  • Имейте в виду, что конечные пользователи ожидают, что техническая поддержка будет говорить на их языке, если ваше программное обеспечение будет переведено. Еще раз, Babelfish, скорее всего, не сделает.

Изменить – Еще несколько пунктов

  • Сделайте переключение между локализациями максимально простым. В Gemsweeper у нас есть горячая клавиша для переключения между разными языками. Это упрощает тестирование.

  • Если вы собираетесь использовать экзотические шрифты, убедитесь, что они включают специальные символы. Шрифты, которые мы выбрали для Gemsweeper, были хороши для английского текста, но нам пришлось добавить немало персонажей, которые существуют только на немецком, французском, португальском, шведском, …

  • Не кодируйте свою собственную локализацию. Вероятно, вам намного лучше работать с открытым исходным кодом, например Gettext . Gettext поддерживает такие функции, как переменные в предложениях или плюрализацию, и обладает прочной структурой. Локализованные ресурсы скомпилированы, поэтому никто не может вмешиваться в них. Кроме того, вы можете использовать такие инструменты, как Poedit, для перевода ваших файлов / проверки чужого перевода и обеспечения того, чтобы все строки были правильно переведены и обновлены до тех пор, пока вы не измените исходный код. Я пробовал работать как самостоятельно, так и используя Gettext, и я должен сказать, что Gettext plus PoEdit был намного лучше.

Редактирование – Еще больше очков

  • Поймите, что разные культуры имеют разные стили формата числа и даты. Схемы нумерации не только различны для каждой культуры, но и для каждой цели в рамках этой культуры. В EN-US вы можете отформатировать номер '-1234'; '-1,234' или (1,234) в зависимости от цели назначения. Понять другие культуры делать то же самое.

  • Знайте, откуда вы получаете информацию о глобализации. Например, Windows имеет настройки для CurrentCulture, UICulture и InvariantCulture. Понять, что каждый означает и как он взаимодействует с вашей системой (они не так очевидны, как вы думаете).

  • Если вы собираетесь делать восточноазиатский перевод, действительно делайте свою домашнюю работу. Восточно-азиатские языки имеют довольно много отличий от языков здесь. Помимо одновременного использования нескольких алфавитов, они могут использовать разные системы макета (сверху вниз) или сетки. Также цифры на восточно-азиатских языках могут быть разными. В en-US вы меняете системы только для ограниченных условий (например, 1 против 1-го), есть дополнительные числовые соображения, кроме запятой и периодом.

Когда мы работали над i18n / l10n вопросами Dreamfall и Age of Conan, мы столкнулись с несколькими проблемами, которые стоит иметь в виду. Некоторые из них мы решили, некоторые были решены для нас, и некоторые из них мы работали. Некоторые из нас никогда не решались …

  • Убедитесь, что все ваши инструменты и весь ваш код поддерживают все кодировки, которые вы хотите использовать, и дважды проверьте это предположение дважды в ходе проекта и еще пару раз, чтобы быть уверенным.

  • Убедитесь, что вы используете шрифт, который поддерживает все языки, которые вы хотите использовать. Большинство шрифтов, которые утверждают, что являются unicode, являются только юникодом в том смысле, что символы, которые у него есть, находятся в правильном кодеге. Это не означает, что у него есть используемые символы для всех кодовых точек.

  • Текстовое обертывание выполняется не только в пространстве, так как некоторые языки не используют пространство для разделения слов (на ум приходит китайский язык). Убедитесь, что ваши текстовые процедуры обрабатывают текст без каких-либо пробелов.

  • Правильное обращение с множеством правильных вещей является сложным в простых случаях, и проклят в жестких случаях. Убедитесь, что вы знаете достаточно о языках, которые будете использовать, чтобы иметь возможность правильно писать код для правильной обработки множественного вопроса. Имейте в виду, что английский (и другие «западные» языки являются одними из простых.

  • Никогда не прерывайте предложения и не стройте строки с ними, чтобы соответствовать переменной, поскольку переменная может быть помещена в другом месте предложения на другом языке. Используйте заполнители.

  • Имейте в виду, что для некоторых языков значение заполнитель может изменить способ написания предложения. Грамматика сложна. Удостоверьтесь, что у вас есть план борьбы с ним. (В частности, убедитесь, что у вас есть способ классифицировать значения, которые вы используете в заполнителях в соответствии с полом, временем и т. Д.).

  • Мои меню и различные списки в приложении отсортированы в алфавитном порядке для каждого языка для упрощения чтения.

списки должны быть отсортированы, меню не должны. имейте в виду, что данный пользователь может захотеть использовать ваше приложение на нескольких языках, он все равно должен найти везде в одном месте.

то же самое с ярлыками, если у вас есть: не переводите их .

Кроме того, помните, что интернационализация и перевод – это две разные вещи, которыми они управляют отдельно.

Я хотел бы высказать следующие замечания – это из некоторых руководящих принципов компании, в которых продукты класса 1 переведены в 31 разных местах. Следуя этим рекомендациям, мы дали нам (нашей команде разработчиков, а не всей компании) наибольшую производительность в переводе.

  • Не пытайтесь повторно использовать фрагменты сообщений об ошибках. Например, не думайте, что, поскольку у вас есть две ошибки: "You selected the wrong menu item" и "That menu item is not yet available" , вы можете извлечь "menu item" в отдельный элемент и использовать его в обоих местах , Все сообщения должны быть автономными, поскольку их переводы могут изменяться в зависимости от контекста.

  • Используйте профессионального переводчика, знающего о технологии. Если вы приблизитесь к службе, подобной BabelFish, вы получите все, что заслуживаете. Например, "Microsoft Windows" является "Microsoft Windows" повсюду на планете, она не стала "Microsoft Fenster" в Германии.

  • Попытайтесь не вставлять переменные в свои сообщения (например, "The %1 has failed" где %1 изменяется динамически), поскольку позиции и, действительно, пол могут меняться: "La table est rubbish" и "L'Homme est drunk" , или "The red table" против "La table rouge" . Лучше использовать родовое существительное с добавленными параметрами: "The item has failed [%1]" .

  • Переводите только те вещи, которые пользователь должен увидеть. Журнальные сообщения в файле журнала (которые будут использоваться только вами) должны быть на английском (или на вашем родном языке), а не переведены на что-то вроде суахили, которое вы все равно не могли прочитать.

  • Меню следует сортировать по функциональности, а не по порядку сортировки.

  • Переводимые единицы должны храниться вне кода и загружаться во время выполнения. Это делает перевод проблемой только доставки внешнего файла, а не попытки перекопать изменения в середине кода. Это также облегчает добавление других языков в будущем.

На данный момент этого достаточно. Лучше остановиться перед тем, как все заснете 🙂

Что касается чисел: на английском, как я понимаю, вы просто используете единственное число с 1 и множественное число с 2 или более. Например: «У вас есть 1 сообщение»; «2 сообщения»; «3 … сообщения». По-русски эти вещи усложняются. Вы используете единственное значение для 1, 21, 31, 41 … 101, 121 (так что для всего, заканчивающегося 1, кроме случаев, когда оно заканчивается на 11). Затем вы используете особый родительный падеж для 2, 3, 4; 22, 23, 24; 32, 33, 34 … 102, 103, 104; 122, 123, 124. И во всех остальных случаях вы используете множественный родительный падеж .

Это не очень сложно реализовать. Трудно, однако, реализовать что-то, что будет знать, как иметь дело с любым априорным неизвестным языком со всей его странностью 🙂

И это всего лишь цифры 🙂

У меня нет много чего добавить к большим ответам до сих пор, но вот несколько вещей, чтобы рассмотреть и проверить.

  • Не делайте предположений. Это правило catch. Легко предположить вещи, которые относятся к региону или языку, и трудно заметить эти предположения.
  • Будьте очень осторожны со строковыми сравнениями. Есть некоторые языки, такие как турецкий, у которых есть буквы, похожие на другие, визуально, но разные.
  • Используйте псевдо-перевод как тест на дым. Если вы прочитали переведенные строки из файла ресурсов, создайте псевдопереведенную версию файла, которая вам все еще понятна, но которая подчеркивает способность и возможности каждой переводимой строки в приложении. Например, выровняйте строку типа «Отмена» с чем-то вроде «CancelXXXX!». так что он будет таким же широким, как и ваше пособие для переведенных строк. Затем вы можете проверить, чтобы каждая строка отображалась полностью. Дополнительный кредит за то, что он также придерживается самого сложного символа, который может быть отображен, чтобы убедиться, что он отображается правильно во всех местах.
  • Не делайте предположений о раскладках клавиатуры. «ASDW» может быть отличным набором управляющих клавиш для клавиатур QWERTY, но жесткое кодирование делает его недружелюбным, если не невозможным, для людей с другими раскладками клавиатуры.
  • Проверьте различные настройки даты, затем проверьте их снова. Я видел проблемы из-за чего-то такого же маленького, как другой формат для «AM / PM» в региональных настройках. Mm / dd / yyyy против dd / mm / yyyy также очень много, но каждая настройка здесь может иметь значение.
  • Проверьте различные форматы чисел, затем проверьте их снова. Например, вы не хотите зависеть от разделителей десятичных или тысяч.
  • Тестирование с и без входа пользователя на сервер. Это может быть больше для Windows, но очень легко получить компонент на сервере, сконфигурированный таким образом, чтобы он использовал зарегистрированные региональные настройки пользователя, когда пользователь вошел в систему, и региональный параметр по умолчанию, когда пользователь не вошел в систему. может вызвать странное, прерывистое поведение.
  • Тест с различными региональными и языковыми настройками. В качестве примера не только Windows имеет региональные и языковые настройки, но IE имеет свой собственный язык. Поведение IE-клиента с указанным в нем первым может не всегда совпадать с именем, указанным первым, например, en-nz.
  • Удостоверьтесь, что ваш переводчик понимает бизнес и языки, а затем перекрестно проверяет кого-то другого. Будьте очень осторожны при использовании терминологии, специфичной для приложения. Если ваша программа использует определенные слова для обозначения чего-то особенного в приложении, убедитесь, что они транслируются одинаково в каждом экземпляре, в том числе в тексте справки. Если у вас есть конкретные языковые цели, вы даже можете зайти так далеко, чтобы перевести такие слова заблаговременно и убедиться, что они плохо переводится на целевые языки. Это скорее исследование продукта, но оно может повлиять на то, какие слова используются в интерфейсе, и все проще, если эти слова находятся на месте с самого начала. Вы также хотите избежать идиом, которые не могут хорошо перевести.

Ладно, мне было больше сказать, чем я думал …

Одна вещь, которую я усвоил, – если у вас есть несколько файлов, которые нужно перевести, добавьте дополнительный тег в имя, чтобы позже вы могли искать всю свою папку для этого тега.

например, вместо названия файла «sample-database.txt» имя английской версии «sample-database-loc-en.txt», итальянской версии «sample-database-loc-it.txt»

Мой первый ответ в StackOverflow, так что простите, если кто-то сказал глупо.

По моему опыту:

  • PHP : gettext был чрезвычайно полезен;
  • незападные языки : UTF-8 везде (код, БД), и до сих пор у нас все хорошо;
  • Есть ли какие-то конкретные проблемы, которые вы испытали на практике? Ломать длинные абзацы для i18n в разные предложения может быть менее дорогостоящим для перевода, если строка повторяется более одного раза на сайте, вам нужно только перевести ее один раз. Но будьте осторожны, если вы фрагментируете текст слишком много переводчиков потеряете контекст;
  • Я видел много проектов и сайтов, позволяя их сообществам предоставлять перевод для своих приложений и контента. Вы рекомендуете это и какие хорошие стратегии для обеспечения хорошего перевода? Если у вас есть очень много добровольцев, заходите на это, но в зависимости от того, сколько текста у вас есть, вам может понадобиться тонна добровольцев. Всегда убедитесь, что у вас есть кто-то, кому вы доверяете, являющимся лидером языкового проекта, чтобы быть корректором, контролирующим точность перевода.
  • Правила сортировки / сортировки могут различаться между языками: ä сортируется по-разному на немецком, чем на шведском. Поэтому сортировка должна быть специфичной для конкретной культуры.
  • Верхняя / нижняя шкала может содержать сюрпризы: немецкий «острый S» символ ß не имеет версии в верхнем регистре и либо преобразован в «SS», либо остается строчным, если точность важна. Турецкий имеет бесстольный строчный регистр i и прописную букву I.
  • Для многоязычных веб-приложений внимательно подумайте о том, как решить, какую версию показывать и как ее использовать в URL. Пользователь всегда должен иметь возможность вручную выбирать язык, и вы хотите, чтобы поисковые системы находили разные языковые версии под разными URL-адресами.
  • Некоторые восточноазиатские языки (а именно, японцы и китайцы, возможно, другие) не имеют пробелов между словами
  • Японцы (возможно, и другие) имеют отдельные версии («полная ширина») арабских цифр и пробелов и даже две версии некоторых своих персонажей (полуширина и полнокашинакакака).

Да, это массовый вопрос. Правильное решение – это очень много работы.

В моей программе я использую целочисленный ключ для каждого фрагмента текста и просматриваю его в файле по мере необходимости в зависимости от языка. В коде нет буквальных строк, только ключей. Я определяю их с «перечислением» на C ++, поэтому я не набираю числа. Я написал утилиту для синхронизации различных языковых файлов, когда добавляю больше перечислений, а переводчики заполняют пробелы.

Каждый ключ также имеет связанную подсказку, изображение, комбинацию клавиш и т. Д.

Что касается времен и дат … опять же, это намного сложнее, чем вы могли бы подумать, но разве PHP не обрабатывает это для вас? (Я не знаю, я парень C ++ …)

PHP представляет строки внутри себя как байтовые потоки и предполагает iso-8859-1 для случаев, когда кодирование имеет значение. По большей части вы можете просто использовать UTF-8 повсюду, и все будет в порядке. Один из них, если ваш сайт принимает данные от своих пользователей, заключается в том, что вы никогда не сможете быть на 100% уверены, что они отправляют контент в правильную кодировку. Вы можете использовать mb_detect_encoding для проверки ввода или использовать скрытое поле с «экзотическими» символами для проверки.

Имейте в виду, что все связанные с строкой функции в PHP, работающие на основе символа, предполагают, что character = byte. Это означает, что вы вообще не можете доверять строковым функциям. Посмотрите на эту страницу для более подробной информации.

Другим хорошим ресурсом для PHP является чит-лист Ника Неттлтона .

Субъект, который очень тесно связан с кодировками / кодировками, представляет собой сортировку . Вам нужны ваши сопоставления, чтобы соответствовать языку / культуре, с которой вы работаете. По крайней мере, в MySql (возможно, в других RDBMS'ах) вы можете указать сортировку на разных уровнях, например, для каждой базы данных, за стол, для столбца и даже в самом запросе.