2008-10-23 4 views
53

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

ответ

63

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

  • 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'); 
+9

, если вы не хотите роли собственной реализации дать http://i18next.com попробовать. поставляется с надлежащей множественной, переменной поддержкой и имеет даже собственный ui для перевода приложения. – jamuhl 2012-09-21 14:50:45

+0

@jamuhl +1, i18next.com выглядит великолепно с первого взгляда. – trejder 2013-07-15 07:57:12

+0

@jamuhl, это очень классно – bychance 2015-08-23 06:59:22

5

Просто найти хорошую статью о i18n в JavaScript:
http://24ways.org/2007/javascript-internationalisation

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

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

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

43

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

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

2 - создать функцию захвата форматирования для устранения различий в локализации. Разрешение formattable строк («{0}») лучше, чем конкатенация («Добро пожаловать в» + значение), по многим причинам:

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

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

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

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

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

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

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

1

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

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

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

В дополнение:

  • Всегда используйте UTF-8 - это звучит глупо, но если вы не в UTF-8 от начала (HTML головки + кодирования JS), вы будете бюст быстро.
  • Используйте английскую строку как ключ к вашим переводам - ​​таким образом, вы не получите таких вещей, как: lang.Приветствие = 'Hello world' - но lang ['Hello world'] = 'Hello world';
9
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 

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

4

После прочтения больших ответов от nickf и Лео, я создал следующий language.js стиля CommonJS управлять всеми моими строками (и возможно, Mustache форматировать их):

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'}); 
0

Для Весенних пучков и 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"]); 

Смотрите также Resolving spring:messages in javascript for i18n internationalization

Смежные вопросы