0

I see the excellent forum before on how to use Json to create a multi language site (Build multiple language website using jQuery and JSON based methods).

I wanted to see if it is possible to use this, but not using the key attribute, instead have as normal HTML. Please see codepen:- https://codepen.io/scottYg55/pen/ZEzpOpm

I can see that the key is being called within the jQuery:

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button class="translate" id="en-gb">English</button>
<button class="translate" id="zh-tw">Chinese</button>

<ul>
  <li class="lang" key="HOME"></li>
  <li class="lang" key="ABOUT"></li>
  <li class="lang" key="CONTACT"></li>
  <li class="lang">Home</li>
</ul>
var arrLang = {
  "en-gb": {
    "HOME": "Home",
    "ABOUT": "About Us",
    "CONTACT": "Contact Us",
  },
  "zh-tw": {
    "HOME": "首頁",
    "ABOUT": "關於我們",
    "CONTACT": "聯絡我們",
  }
};

// The default language is English
var lang = "en-gb";

// Check for localStorage support
if ('localStorage' in window) {
  var usrLang = localStorage.getItem('uiLang');
  if (usrLang) {
    lang = usrLang
  }
}

console.log(lang);

$(document).ready(function() {
  $(".lang").each(function(index, element) {
    $(this).text(arrLang[lang][$(this).attr("key")]);
  });
});

// get/set the selected language
$(".translate").click(function() {
  var lang = $(this).attr("id");

  // update localStorage key
  if ('localStorage' in window) {
    localStorage.setItem('uiLang', lang);
    console.log(localStorage.getItem('uiLang'));
  }

  $(".lang").each(function(index, element) {
    $(this).text(arrLang[lang][$(this).attr("key")]);
  });
});

I have changed this to HTML but still no luck, anyone have any ideas?

Thank you!

Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339
Brad
  • 459
  • 2
  • 9
  • `I wanted to see if it is possible to use this, but not using the key attribute, instead have as normal HTML` That doesn't make much sense, as the `key` is required to know which language to lookup in the JS object. – Rory McCrossan Aug 19 '19 at 14:33
  • Yes I wondering if this could be changed, so it targets just the HTML within the div, and not the key – Brad Aug 19 '19 at 14:33
  • Well you could go off of text, but once it is not english, you would not be able to swap it easily. The key is what simplifies it. – epascarello Aug 19 '19 at 14:35
  • @epascarello, i misread the question. – Mox Aug 19 '19 at 14:38
  • Is using a key best practise for an entire website? Because we will be looking to switch languages for large pages, so I was wondering if there was a way to target the HTML rather than the key. Or would best practise always be to use the key? And then wrap the text needing to be changed within or
    etc...?
    – Brad Aug 19 '19 at 14:38
  • The thing is with this, it can be simplified. Drop the class and leave the attribute. – epascarello Aug 19 '19 at 14:39
  • Just a simple remarks if you want to have a really clean code, the HTML5 specifications allow custom attributes, but you need to prefix them with "data-". More info on : https://www.w3schools.com/tags/att_global_data.asp – JardonS Aug 19 '19 at 14:41
  • @Brad, have you considered using the "id" attribute? – Mox Aug 19 '19 at 14:41
  • So would there be a way to target all HTML instead of looking for the key? E.g. I want to find every word that says 'Home', not just the word' Home' within the key – Brad Aug 19 '19 at 14:43
  • 1
    Problem is you would have to change how it would work..... And once you change it once from English to Chinese, you would not have a simple look up since the text would be in Chinese. What you are gaining by not having to set the key is making it more complex. – epascarello Aug 19 '19 at 14:48
  • @Brad, don't think replacing every "Home" word is a good idea. Imagine a paragraph that contains the word "Home", that word will be translated to "首頁" which will be a bug. – Mox Aug 19 '19 at 14:51
  • Sure, so using 'Key' is okay for websites? – Brad Aug 19 '19 at 14:53
  • also instead of using key, i suggest you use class attribute, it will simplify your code a little. – Mox Aug 19 '19 at 14:53
  • for(var key in arrLang[lang]) { $('.'+key).text(arrLang[lang][key]); } – Mox Aug 19 '19 at 14:54
  • if you feel that there are too many occurrence and it is impacting your page performance, consider using vanilla js over jquery. jquery is notorious for its poor performance – Mox Aug 19 '19 at 14:55
  • Hi Mox, could you please provide a code example of changing this to class? Thanks! – Brad Aug 19 '19 at 15:23

1 Answers1

0

If you want to simplify, drop the css class and just use the reference.

var arrLang = {
  "en-gb": {
    "HOME": "Home",
    "ABOUT": "About Us",
    "CONTACT": "Contact Us",
  },
  "zh-tw": {
    "HOME": "首頁",
    "ABOUT": "關於我們",
    "CONTACT": "聯絡我們",
  }
}

function setText (lang) {
  // localStorage.setItem('uiLang', lang);
  $("[data-key]").text( function () {
    var key = $(this).data('key')
    return arrLang[lang][key] || key
  })
}

$(".translate").on("click", function (e) {
  e.preventDefault();
  setText(this.id)
});

// setText(localStorage.getItem('uiLang') || 'en-gb');
setText('en-gb'); 
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button class="translate" id="en-gb">English</button>
<button class="translate" id="zh-tw">Chinese</button>

<ul>
  <li data-key="HOME"></li>
  <li data-key="ABOUT"></li>
  <li data-key="CONTACT"></li>
</ul>

could you do it with just the text? Yes.... but it is more complex and I would end up still using a data attribute....

epascarello
  • 204,599
  • 20
  • 195
  • 236
  • Okay, thank you! Can you input HTML with the data-key? So you can have a href links here? – Brad Aug 19 '19 at 15:11