User:Taw/Practical multilingual messages
< User:Taw
At the moment:
- Interface messages may be shown in any language (except for Commons-specific customizations, which must stay in English).
- Messages that are de facto interface messages (like {{disambig}}, or license boxes), but are implemented as templates, not by the software, are shown only in English.
- Various descriptions are shown in more than one language, but usually it's just a few.
Issue 2 is a serious problem. People who don't understand English won't be able to recognize the messages. People who do understand English may still feel uncomfortable with it.
Issue 3 is likely to become a serious problem as more languages are added.
But both issues are possible to solve without any software support, and with just a little bit of Javascript.
The idea is as follows:
- Item that has versions in many languages in put inside a "<div class="multi">...</div>" tag.
- Inside that tag there are many DIVs, one per language, for example <div lang="pl">Msg</div>".
- User sets language preferences somewhere, for example "pl, en, de" (if Polish version is available, show it, else if English version is available, show the English version, then try German, if none of them is available, just show everything, maybe something will be understandable)
- The default is to show everything, NOT to show English message
- The Javascript like one below loads, and hides all unnecessary messages.
- Users with Javascript disabled (like Googlebot) see the message in all languages
- If some messages were hidden, display a show/hide switch. It may be useful sometimes. (I think this toggle should contain an image, not a text in English)
To implement this we may do:
- Make templates {{div_multi}}, {{div_en}} etc. (and maybe also {{span_multi}})
- Change interface templates like {{disambig}} and the licenses into {{div_multi}} format.
- People who don't have div_multi enabled
- Everyone may paste a JavaScript code like one below (not exactly the same, something else must be used in place of onload) into their js, modifying the pref = ["en", "pl"] appropriately
- People who do that see only messages in their preferred language
- We bug developers until they implement some way of accessing language preferences from Javascript code, so exactly the same code may be used by everyone, without editing pref in the code
- The Javascript is copied into sitewide js
- Everyone can set their language preferences on the preferences page, and it just works
- We may start tagging non-system messages, like image descriptions, with language tags too.
Example
[edit]<html> <head> <title>Test of multi-language display</title> <script> function setLang() { // Set your linguistic preferences here var pref = ["en", "pl"]; /***********************************************/ // The code follows // index_all_lang_toggle doesn't have to be a global variable, // we only add new toggles inside this function var index_all_lang_toggle = 0; var divs = document.getElementsByTagName("div"); for(var i=0; i<divs.length; i++) { var d = divs[i]; if (d.className == "multi_lang") { var cn = d.childNodes; var available = new Array(); for(var j=0; j<cn.length; j++) { var child = cn.item(j); /* In HTML it's "DIV", in XHTML it's "div". * For forward compatibility, both cases must be supported. */ if(child.tagName == "DIV" || child.tagName == "div") { var clang = child.getAttribute("lang"); if(clang) available[clang] = true; } } /* We know what's available and we know user preferences, * Decide what to keep. * * If we hid anything, display a switch to show/hide other languages */ var hid_something = false; var preferred_language; for(var j=0; j<pref.length; j++) { var p = pref[j]; // A match, finally if(available[p]) { hid_something = hide_extra_lang_divs(cn, p); preferred_language = p; break; } } if(hid_something) { var all_lang_toggle = document.createElement("a"); all_lang_toggle.className = 'all_lang_toggle'; all_lang_toggle.setAttribute('href', 'javascript:show_all_lang('+index_all_lang_toggle+',\''+preferred_language+'\')'); all_lang_toggle.setAttribute('id', 'all_lang_toggle_' + index_all_lang_toggle); var all_lang_toggle_text = document.createTextNode("(show other languages)"); all_lang_toggle.appendChild(all_lang_toggle_text); d.insertBefore(all_lang_toggle, d.firstChild); index_all_lang_toggle ++; } } } } function hide_extra_lang_divs(div_list, preferred_language) { var hid_something = false; for(var k=0; k<div_list.length; k++) { var child = div_list.item(k); if(child.tagName == "DIV" || child.tagName == "div") { var clang = child.getAttribute("lang"); if (clang && clang != preferred_language) { child.style.display = 'none'; hid_something = true; } } } return hid_something; } function show_all_lang(i, preferred_language) { var all_lang_toggle = document.getElementById('all_lang_toggle_' + i); var cn = all_lang_toggle.parentNode.childNodes; for(var k=0; k<cn.length; k++) { var child = cn.item(k); if(child.tagName == "DIV" || child.tagName == "div") { child.style.display = 'block'; } } all_lang_toggle.firstChild.data = "(hide other languages)"; all_lang_toggle.setAttribute('href', 'javascript:hide_other_lang('+i+',\''+preferred_language+'\')'); } function hide_other_lang(i, preferred_language) { var all_lang_toggle = document.getElementById('all_lang_toggle_' + i); hide_extra_lang_divs(all_lang_toggle.parentNode.childNodes, preferred_language); all_lang_toggle.firstChild.data = "(show other languages)"; all_lang_toggle.setAttribute('href', 'javascript:show_all_lang('+i+',\''+preferred_language+'\')'); } </script> </head> <body onload='setLang()'> <div class='multi_lang'> <div lang='en'>English</div> <div lang='pl'>Polski</div> <div lang='de'>Deutsch</div> </div> <hr> <div class='multi_lang'> <div lang='pl'>Polski</div> <div lang='de'>Deutsch</div> </div> <hr> <div class='multi_lang'> <div lang='ja'>nihongo</div> <div lang='de'>Deutsch</div> </div> </body> </html>