Как сохранить изменяющееся состояние языка в expressJS - PullRequest
0 голосов
/ 11 октября 2018

Я работаю над проектом, используя nodeJs, handlebars и expressJs framework.Я добавляю функциональность изменения языка с помощью модуля i18n-express . Этот модуль добавляет строку запроса в конце URL, когда мы собираемся изменить язык.Теперь проблема в том, что когда я перемещаю одну страницу на другую, тогда строка запроса удаляется и теряет свое состояние. Как я могу поддерживать состояние языка ??если пользователь выбирает французский язык, то все страницы открываются на французском языке.Это то, что я хочу.

Код:

var i18n =  require("i18n-express");

app.use(i18n({
  translationsPath: path.join(__dirname, 'lang'), // <--- use here. Specify translations files path.
  siteLangs: ["ar","en","cn","fr","ge","he","hu","it","ja","ko","es","ru"],
  cookieLangName : 'ulang',
  textsVarName: 'translation'  
}));

Ссылка для изменения языка

<a href="#!" id="{{icon}}" onclick=" return changeLanguage(this)"></a>

Функция щелчка для изменения языка

function changeLanguage(event){
   $('#languages img').attr('src','/images/flag-icons/'+event.id+'.png');
   var url = window.location.href;
   url = url.split("?")[0];
   url += '?clang='+event.id;
   window.location.href = url;
   localStorage.setItem("clang", '?clang='+event.id); //event.id returns locale name such as en, ar, sp, fr etc.
   //console.log(url);
}

Ответы [ 4 ]

0 голосов
/ 22 октября 2018

Требование, насколько я понимаю, сводится к следующему:

Если конечный пользователь выбрал язык, выбор должен всегда быть прозрачным в URL, чтобы обеспечить надлежащее функционирование перевода.модуль.Выполнение этого требования не должно приводить к ненужной перезагрузке страницы.Однако в рамках этого вопроса игнорируется тот факт, что при холодном запуске, где clang=xx не существует, потребуется ручное перенаправление для загрузки правильного содержимого, поскольку предыдущий выбор пользователя известен только клиенту.

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

Пропатченный HTML

<a href="#!" id="{{icon}}" onclick="return loadContentInSelectedLanguage(this.id)"></a>

Пропатченный JS:

function processLanguageSelection(selectedLang) {

  highlightCurrentlySelectedLang(selectedLang);
  saveSelectedLangAcrossSession("clang", selectedLang);

  reloadContentInSelectedLang(selectedLang);
}

function highlightCurrentlySelectedLanguage(selectedLang) {
  $('#languages img').attr('src', '/images/flag-icons/' + selectedLang + '.png');
}

function saveSelectedLangAcrossSession(entryKey, selectedLang) {
  window.localStorage.setItem(entryKey, selectedLang);
}

function reloadContentInSelectedLang(selectedLang) {
  var search = window.location.search || "?";

  if (/clang=\w{2}/.test(search)) {
    search = search.replace(/clang=\w{2}/, "clang=" + selectedLang);
  } else {
    search += ("?" === search ? "clang=" : "&clang=") + selectedLang;
  }

  window.history.replaceState(null, "", search);
  window.location.reload();
}

Ты почти там , как я уже сказал. Итак, что же в конечном итоге получить? - Отсутствует фишка в следующем: предыдущий выбор пользователя должен применяться только тогда, когда страница начинает загружаться.И любое необходимое перенаправление должно быть выполнено как можно раньше, прежде чем браузер начнет обрабатывать тело документа. Естественно, это означает, что часть ваших скриптов с этой ответственностью должна быть первой, которая запускается внутри <head>...</head> section.

<head>
  <script>
    (function() {
      var previouslySelectedLanguage = window.localStorage.getItem("clang");

      if (/clang=\w{2}/.test(window.location.search)) {
        // correct content should have been loaded in this case
        // otherwise the server needs fixing, but that's not
        // in the scope of this question.

        // determine selectedLang from window.location.search, then..
        highlightCurrentlySelectedLanguage(selectedLang);

        if (!previouslySelectedLanguage || "selectedLang" !== previouslySelectedLanguage) {
          saveSelectedLangAcrossSession("clang", selectedLang);
        }

        return;
      }

      if (previouslySelectedLanguage) {
        // redirect
        reloadContentInSelectedLang(previouslySelectedLanguage);
      }
    })();

  </script>
</head>

Обратите внимание, что примеры, приведенные в этом ответе, не готовы к работе.Проявляйте должную осмотрительность, гарантируя, что они надежны, устойчивы и соответствуют другим стандартам, требуемым в вашей организации.Например, это регулярное выражение /clang=\w{2}/ делает смелое предположение, которое не всегда может быть правдой.

0 голосов
/ 19 октября 2018

Я рекомендую вам Lingua для ExpressJS

По сути, Lingua - это промежуточное ПО для Express.js, которое помогает вам легко интернационализировать ваше веб-приложение.Он определяет язык пользовательского агента и передает ресурсы i18n в ваши представления.

$ npm install -s lingua

var express = require('express'),
    lingua  = require('lingua');

// Express app configuration code and lingua init.
app.configure(function() {

app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');

// Lingua configuration
app.use(lingua(app, {
    defaultLocale: 'en',
    path: __dirname + '/i18n'
}));

app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.static(__dirname + '/public'));
app.use(app.router);

Языковые файлы

'./i18n/en.json' and './i18n/de-de.json').

// en.json
    {
        "title": "Hello World",
        "content": {
            "description": "A little description."
        }
    }

// de-de.json
    {
        "title": "Hallo Welt",
        "content": {
            "description": "Eine kleine Beschreibung."
        }
    }

И вы можете легко реализовать это на своих страницах с помощью:

<h1><%= lingua.title %></h1> <!-- out: <h1>Hello World</h1> -->
<p><%= lingua.content.description %></h1> <!-- out: <p>A little description.</p> -->
0 голосов
/ 20 октября 2018

Почему бы вам не передать куки с языком вместо параметра запроса?У i18n-express есть опция с именем cookieLangName, которую вы уже настроили на стороне сервера (cookieLangName: 'ulang').Установка cookieLangName заставляет i18n-express читать язык из куки с именем, которое вы передаете.Все, что вам нужно, это установить этот файл cookie в вашем клиентском скрипте - внутри функции changeLanguage - и он сделает свое дело:

function changeLanguage(event){
   $('#languages img').attr('src','/images/flag-icons/'+event.id+'.png');
   document.cookie = `ulang=${event.id}; path=/`;

   localStorage.setItem("ulang", `ulang=${event.id}; path=/`); // you can still save it to localStorage and synchronize it when cookie is removed
}
0 голосов
/ 11 октября 2018

На стороне клиента, если вы можете установить элемент в локальном хранилище, вы также можете получить тот же элемент и использовать его значение, чтобы отправить его также в строку запроса.Таким образом, вам в основном нужна дополнительная функция в вашем клиентском javascript, которая будет получать элемент при каждом открытии страницы.

    function getParameterByName(name, url) {
        if (!url) url = window.location.href;
        name = name.replace(/[\[\]]/g, '\\$&');
        var regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)'),
            results = regex.exec(url);
        if (!results) return null;
        if (!results[2]) return '';
        return decodeURIComponent(results[2].replace(/\+/g, ' '));
    }

    function checkLanguageFromLocalStorage(){
        var clang = getParameterByName('clang');
        if (clang == null) {
            if (localStorage.getItem("clang") != null) {
                var clang = localStorage.getItem("clang");
                var url = window.location.href;
                url = url.split("?")[0];
                url += '?clang='+clang;
                window.location.href = url;
            }
        }
    }

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