Лучшая практика javascript и мультиязычность - PullRequest
59 голосов
/ 23 октября 2008

Какова лучшая практика для мультиязычного веб-сайта, использующего DOM-манипулирование с помощью JavaScript? Я строю некоторые динамические части сайта, используя JavaScript. Моей первой мыслью было использование массива с текстовыми строками и языковым кодом в качестве индекса. Это хорошая идея?

Ответы [ 7 ]

69 голосов
/ 23 октября 2008

Когда я создавал многоязычные сайты раньше (не очень большие, так что это может не очень хорошо масштабироваться), я сохраняю серию «языковых» файлов:

  • lang.en.js
  • lang.it.js
  • lang.fr.js

Каждый из файлов объявляет объект, который в основном является картой от ключевого слова к языковой фразе:

// lang.en.js
lang = {
    greeting : "Hello"
};

// lang.fr.js
lang = {
    greeting : "Bonjour"
};

Динамически загружайте один из этих файлов, а затем все, что вам нужно сделать, это указать ключ на карте:

document.onload = function() {
    alert(lang.greeting);
};

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

var l = new Language('en');
l.get('greeting');
50 голосов
/ 23 октября 2008

При проектировании поддержки мультиязычности необходимо помнить несколько вещей:

1 - Отделение кода от данных (т. Е. Не кодировать строки напрямую в ваши функции)

2 - создать функцию ловушки форматирования для обработки различий в локализации. Разрешение форматируемых строк ( "{0}" ) лучше конкатенации ( "Welcome to" + value ) по многим причинам:

  • на некоторых языках число форматируется как 1,234,678,00 вместо 1,234,567,00
  • множественное число часто не так просто, как добавление "s" в конце единственного числа
  • правила грамматики различны и могут влиять на порядок вещей, поэтому вы должны разрешить добавление динамических данных после ловушки перевода: например, "Welcome to {0}" превращается в " {0} he youkoso " по-японски (заметьте, это происходит почти на каждом языке).

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

4 - Ни при каких обстоятельствах не подключайте выходные данные базы данных к утилите переводчика . Если у вас есть многоязычные данные, создайте отдельные таблицы / строки в вашей базе данных. Я видел, как люди довольно часто ошибаются (обычно для стран и штатов / провинций в формах).

5 - Создание явных правил практики кодирования для создания ключей. Функция утилиты форматирования (которая будет выглядеть примерно так: translate ("hello world") будет принимать ключ в качестве параметра, а ключи с небольшими изменениями делают обслуживание очень раздражающим. Например, вы можете получить три ключи в следующем примере: «введите свое имя», «введите свое имя:», «введите свое имя:». Выберите один формат (например, без двоеточия, обрезанный) и обнаруживайте расхождения в проверках кода. Не выполняйте эту фильтрацию программно , так как это может вызвать ложные срабатывания.

6. Помните, что HTML-разметка потенциально может потребоваться в таблице перевода (например, если вам нужно выделить слово в предложении или иметь медицинские сноски). Проверьте это экстенсивно.

7 - Есть несколько способов импорта языковых строк. В идеале у вас должно быть несколько версий файла language.lang.js, переключаться между ними с помощью кода на стороне сервера и ссылаться на файл в нижней части HTML-файла. Извлечение файла через AJAX также является альтернативой, но может привести к задержкам. Встраивать language.js в ваш основной файл кода не рекомендуется, так как вы теряете преимущества кеширования файлов.

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

12 голосов
/ 18 июля 2014
function Language(lang)
{
    var __construct = function() {
        if (eval('typeof ' + lang) == 'undefined')
        {
            lang = "en";
        }
        return;
    }()

    this.getStr = function(str, defaultStr) {
        var retStr = eval('eval(lang).' + str);
        if (typeof retStr != 'undefined')
        {
            return retStr;
        } else {
            if (typeof defaultStr != 'undefined')
            {
                return defaultStr;
            } else {
                return eval('en.' + str);
            }
        }
    }
}

После добавления этого на свою страницу вы можете работать с ним так:

var en = {
    SelPlace:"Select this place?",
    Save:"Saved."
};

var tr = {
    SelPlace:"Burayı seçmek istiyor musunuz?"
};

var translator = new Language("en");
alert(translator.getStr("SelPlace")); // result: Select this place?
alert(translator.getStr("Save")); // result: Saved.
alert(translator.getStr("DFKASFASDFJK", "Default string for non-existent string")); // result: Default string for non-existent string

var translator = new Language("tr");
alert(translator.getStr("SelPlace")); // result: Burayı seçmek istiyor musunuz?
alert(translator.getStr("Save")); // result: Saved. (because it doesn't exist in this language, borrowed from english as default)
alert(translator.getStr("DFKASFASDFJK", "Default string for non-existent string")); // result: Default string for non-existent string

Если вы позвоните в класс с языком, который вы не определили, будет выбран английский ( en ).

5 голосов
/ 12 мая 2015

После прочтения великолепных ответов nickf и Leo я создал следующий язык languageJ.Si в стиле CommonJS для управления всеми моими строками (и, необязательно, Усы для их форматирования):

var Mustache = require('mustache');

var LANGUAGE = {
    general: {
        welcome: "Welcome {{name}}!"
    }
};

function _get_string(key) {
    var parts = key.split('.');
    var result = LANGUAGE, i;
    for (i = 0; i < parts.length; ++i) {
        result = result[parts[i]];
    }
    return result;
}

module.exports = function(key, params) {
    var str = _get_string(key);
    if (!params || _.isEmpty(params)) {
        return str;
    }
    return Mustache.render(str, params);
};

И вот как я получаю строку:

var L = require('language');
var the_string = L('general.welcome', {name='Joe'});
5 голосов
/ 23 октября 2008

Только что нашел хорошую статью о i18n в javascript:
http://24ways.org/2007/javascript-internationalisation

Хотя простой поиск в Google с i18n + javascript выявляет множество альтернатив.

В конце концов, это зависит от того, насколько глубина вы хотите, чтобы это было. Для пары языков достаточно одного файла.

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

1 голос
/ 24 октября 2008

Вы должны посмотреть, что было сделано в классических компонентах JS - взять такие вещи, как Dojo, Ext, FCKEditor, TinyMCE и т. Д. Вы найдете много хороших идей.

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

Одна вещь, которую нужно иметь в виду, это эволюция языкового набора (когда ваш код эволюционирует, вам нужно будет перевести все это или нет). Мы храним переводы в PO-файлах (Gnu Gettext), и у нас есть скрипт, который преобразует PO-файл в готовый для использования JS-файл.

Дополнительно:

  • Всегда используйте UTF-8 - это звучит глупо, но если вы не находитесь в utf-8 с самого начала (HTML head + JS кодировка), вы быстро обанкротитесь.
  • Используйте английскую строку в качестве ключа к вашим переводам - ​​таким образом, вы не будете иметь дело с такими вещами, как: lang.Greeting = 'Hello world' - но lang ['Hello world'] = 'Hello world';
0 голосов
/ 25 мая 2017

Для пакетов Spring и JavaScript существует простое решение: создать массив i18n в шаблоне (например, JSP) и использовать его в JavaScript:

JSP:

<html>
<script type="text/javascript">
    var i18n = [];
    <c:forEach var='key' items='<%=new String[]{"common.deleted","common.saved","common.enabled","common.disabled","...}%>'>
        i18n['${key}'] = '<spring:message code="${key}"/>';
    </c:forEach>
</script>
</html>

А в JS:

alert(i18n["common.deleted"]);

См. Также Разрешающая пружина: сообщения в JavaScript для интернационализации i18n

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...