Разрешение spring: сообщения в javascript для интернационализации i18n

Я пытаюсь интернационализировать некоторые из наших кодов. У меня есть страница в JSPX, которая использует <spring:message> тег для разрешения строк из . Это отлично работает для HTML и CSS, который находится на странице JSPX, однако там файл javascript получен и заменяет <spring:message> тег для строки там просто означает, что он печатается дословно.

мой jspx источники javascript, как так:

<spring:theme code="jsFile" var="js" />
<script type="text/javascript" src="${js}" />

JS, где я ищу замену строка ниже:

buildList('settings', [{
    name: '<spring:message code="proj.settings.toggle" javaScriptEscape="true" />',
    id:"setting1",
    description: '<spring:message code="proj.settings.toggle.description" javaScriptEscape="true" />',
    installed: true
}]);

и, наконец, сообщение.свойства что-то вроде:

proj.settings.toggle=Click here to toggle
proj.settings.toggle.description=This toggles between on and off

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

Я также должен отметить, что эти файлы находятся вне папки WEB-INF, но путем размещения ReloadableResourceBundleMessageSource в корне applicationContext.xml весенние теги подобраны.

Спасибо за любую помощь!

3 ответов


мне кажется, что вы хотите сделать, это обработать JS-файл как JSP-файл и разрешить его содержимое с помощью тега spring:message.
Я бы не стал этого делать.

обычно JS i18n выполняется одним из двух способов:

  • путем написания массива переведенных строк из JSP page
  • путем создания фильтра перевода и предоставления предварительно переведенного JS-файла запрашивающему клиенту

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

<script type="text/javascript">
  var strings = new Array();
  strings['settings.toogle'] = "<spring:message code='proj.settings.toggle' javaScriptEscape='true' />";
  strings['settings.toogle.description'] = "<spring:message code='proj.settings.toggle.description' javaScriptEscape='true' />";
</script>
<spring:theme code="jsFile" var="js" />
<script type="text/javascript" src="${js}" />

и в ваш JS файл:

buildList('settings', [{
    name: strings['settings.toggle'],
    id:"setting1",
    description: strings['settings.toggle.description'],
    installed: true
}]);

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

Edit: дополнительный ввод

мы предоставляем переводы в JS-файлы по этой причине. Обычно причина в том, что мы хотим создать некоторую часть пользовательского интерфейса динамически. Есть также случаи, когда нам нужно локализовать какой-то сторонний компонент, мой ответ выше имеет дело с ними довольно хорошо.
Для случаев, когда мы хотим создавать части пользовательского интерфейса динамически, действительно имеет смысл использовать шаблоны, а не объединять HTML-теги в JavaScript. Я решил написать это, потому что это делает для гораздо более чистого (и, возможно, многоразового) решения.
Поэтому вместо передачи переводов на JavaScript можно создать шаблон и поместить его на страницу (мой пример будет использовать руль.js, но я считаю, что можно использовать любой другой двигатель):

<script id="article" type="text/x-handlebars-template">
  <div class="head">
    <p>
      <span>
        <spring:message code="article.subject.header" text="Subject: " />
      </span>{{subject}}</p>
  </div>
  <div class="body">
    {{{body}}}
  </div>
</script>

на стороне клиента (то есть в JavaScript) все, что вам нужно сделать, это получить доступ к шаблону (пример ниже, очевидно, использует jQuery) и скомпилировать:

var template = Handlebars.compile($("#article").html());
var html = template({subject: "It is really clean",
  body: "<p>Don't you agree?</p><p>It looks much better than usual spaghetti with JavaScript variables.</p>"
});
$("#someDOMReference").html(html);

несколько вещей Примечание здесь:

  • <spring:message /> теги escape как HTML, так и JS по умолчанию, нам не нужно указывать javaScriptEscape атрибут
  • имеет смысл предоставить на <spring:message /> тег, поскольку он может использоваться как резервный (если нет перевода для данного языка), а также комментарий (что означает этот элемент). Можно даже создать инструмент, который будет сканировать файлы для <spring:message /> теги и автоматически создавать файлы свойств
  • для предотвращения Руль от побега содержимого HTML, я использовал triple {{{curly braces}}}

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


Спасибо за ваш ответ. Вот более общее решение.

идея состоит в том, чтобы предоставить динамический javascript файл с именем "string.js", содержащий ассоциативный массив сообщений, зарегистрированных в пакете ресурсов java, с использованием текущего языка пользователя.

1) Создайте метод весной контроллер чтобы загрузить все ключи ресурсов из пакета ресурсов и вернуть представление "весна.jsp"

@RequestMapping(value="strings.js")
public ModelAndView strings(HttpServletRequest request) {
    // Retrieve the locale of the User
    Locale locale = RequestContextUtils.getLocale(request);
    // Use the path to your bundle
    ResourceBundle bundle = ResourceBundle.getBundle("WEB-INF.i18n.messages", locale);  
    // Call the string.jsp view
    return new ModelAndView("strings.jsp", "keys", bundle.getKeys());
}

2) реализовать посмотреть "строк.jsp"

<%@page contentType="text/javascript" pageEncoding="UTF-8"
%><%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"
%><%@taglib prefix="spring" uri="http://www.springframework.org/tags"
%>var messages = new Array();

<c:forEach var="key" items="${keys}">messages["<spring:message text='${key}' javaScriptEscape='true'/>"] = "<spring:message code='${key}' javaScriptEscape='true' />";
</c:forEach>

3) импорт "весна.js " в исходном коде HTML. Массив сообщений доступен и загружен с правильным языком.

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


в дополнение к ответу @Toilal вы можете добавить вспомогательную функцию к строкам.jsp для лучшего использования массива переводов:

<%@page contentType="text/javascript" pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@taglib prefix="spring" uri="http://www.springframework.org/tags"%>
var messages = new Array();

<c:forEach var="key" items="${keys}">messages["<spring:message text='${key}' javaScriptEscape='true'/>"] = "<spring:message code='${key}' javaScriptEscape='true' />";
</c:forEach>

/**
 * Tranlate a String by key, if key is not defined return the key.
 *  
 * @author Pedro Peláez <aaaaa976 at gmail dot com>, Drupal/Wordpress authors, and others
 * @param {String} key
 * @returns {String}
 */
function t(key) {
    if (messages[key]) {
        return messages[key];
    }
    return key;
}

тогда при необходимости просто используйте:

alert(t("menu.section.main"));