tschortsch tschortsch - 7 months ago 141
Javascript Question

jquery-i18next - usage, change language by user, load translation from files

I was looking for an internationalization framework and came across jqueryi-18next.js. I'm actually totally confused by using this plugin as the code in the sample file is different from the documentation.

My modified sample.html where I added two more language resources (de, fr), it is working fine when I change the "lng" value in the script.



i18next.init({
lng: 'de',
resources: {
en: {
translation: {
nav: {
page1: 'Page One',
page2: 'Page Two',
page3: 'Page Three'
}
}
},
de: {
translation: {
nav: {
page1: 'Seite Eins',
page2: 'Seite Zwei',
page3: 'Seite Drei'
}
}
},
fr: {
translation: {
nav: {
page1: 'Page Un',
page2: 'Page Deux',
page3: 'Page Trois'
}
}
}
}
}, function(err, t) {
i18nextJquery.init(i18next, $);
$('.nav').localize();
});

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-i18next/0.0.14/i18next-jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/i18next/2.0.22/i18next.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.0/jquery.js"></script>
<ul class="nav">
<li><a href="#" data-i18n="nav.page1"></a></li>
<li><a href="#" data-i18n="nav.page2"></a></li>
<li><a href="#" data-i18n="nav.page3"></a></li>
</ul>





According to the docs the plugin is initialized using:

jqueryI18next.init(i18nextInstance, $, {...


Furthermore, if I load the jquery-i18next.min.js from the repository it doesn't work at all, I can only see the list item dots.

What I basically would like to achieve is following:


  1. Changing the language using anchor links (en/de/fr) without reloading the whole page.

  2. Load the translations from files. I did save three translation.json files according to the docs in locales with sub folders (en/de/fr) but without any success, only list item dots are visible! :(



I don't know how to do this and therefore I would really appreciate any help!

Thank you very much in advance!

Answer

I think I can answer both parts of your question.

  1. You can add some anchor links and make them control the language quite easily. To change the language you just need to call i18next.chngeLanguage to set the new language and then call $(elem).localize() for every element you localize initially. In this example the language is updated if any of the .lang-select links are clicked.

i18next.init({
        lng: 'de',
        resources: {
          en: {
            translation: {
              nav: {
                page1: 'Page One',
                page2: 'Page Two',
                page3: 'Page Three'
              }
            }
          },
          de: {
            translation: {
              nav: {
                page1: 'Seite Eins',
                page2: 'Seite Zwei',
                page3: 'Seite Drei'
              }
            }
          },
          fr: {
            translation: {
              nav: {
                page1: 'Page Un',
                page2: 'Page Deux',
                page3: 'Page Trois'
              }
            }
          }
        }
      }, function(err, t) {
        i18nextJquery.init(i18next, $);
        $('.nav').localize();

        $('.lang-select').click(function() {
          i18next.changeLanguage(this.innerHTML);
          $('.nav').localize();
        });
      });
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-i18next/0.0.14/i18next-jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/i18next/2.0.22/i18next.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.0/jquery.js"></script>
<a href="#" class="lang-select">en</a>
<a href="#" class="lang-select">de</a>
<a href="#" class="lang-select">fr</a>
<ul class="nav">
  <li><a href="#" data-i18n="nav.page1"></a></li>
  <li><a href="#" data-i18n="nav.page2"></a></li>
  <li><a href="#" data-i18n="nav.page3"></a></li>
</ul>

  1. To load from files on the server you need to use the i18next-xhr-backend for i18next. This examle won't be able to load the translations here but if you setup the directory structure shown below on the server then it should be able to load the translations as needed. You can also provide other values for loadPath to control how you want to store the files. To store all namespaces for each language in a single file use loadPath: '/locales/{{lng}}.json' or to store all languages in a single file use loadPath: '/locales.json'.

i18next
  .use(i18nextXHRBackend)
  .init({
      lng: 'de',
      backend: {
          loadPath: '/locales/{{lng}}/{{ns}}.json'
      }
    }, function(err, t) {
      jqueryI18next.init(i18next, $);
      $('.nav').localize();

      $('.lang-select').click(function() {
        i18next.changeLanguage(this.innerHTML);
        $('.nav').localize();
      });
  });
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-i18next/0.0.14/i18next-jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/i18next/2.0.22/i18next.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.0/jquery.js"></script>
<a href="#" class="lang-select">en</a>
<a href="#" class="lang-select">de</a>
<a href="#" class="lang-select">fr</a>
<ul class="nav">
  <li><a href="#" data-i18n="nav.page1"></a></li>
  <li><a href="#" data-i18n="nav.page2"></a></li>
  <li><a href="#" data-i18n="nav.page3"></a></li>
</ul>

The directory structre required:

locales
├── de
│   └── translation.json
├── dev
│   └── translation.json
├── en
│   └── translation.json
└── fr
    └── translation.json

Example translation.json:

{
    "nav": {
        "page1": "Seite Eins",
        "page2": "Seite Zwei",
        "page3": "Seite Drei"
    }
}
Comments