blog

January 23, 2019

Multi-language website.

keywords:

This may come in handy:

    Working on the recent project inspired Me to invent a multi-language website mechanism which I desired for a long time now. Finally I have achieved a working solution which I suppose could be well-enough to establish however many language version on whatever website, including those based on Blogger.

    One thing I especially like in this concept is that - thanks to jQuery - it is pretty universal. This means that You can use it on Blogger websites as well as in case of many others: the only thing You need is to have access to the source code.

    Another nice thing is that this solution seems to be pretty easy to apply on websites that already exist - so You don't necessarily need to start working on Your project, keeping a multi-language mechanism in mind from the very beginning. You'll see that there isn't so much of a necessary work to do.

    In this article I will describe how to implement a multi-language solution on an existing website. I'll try to describe it in a way which should enable You to benefit from - regardless of using Blogger platform or not. So, let's do it :) !

    First of all, it could be easier to grasp how it works with a little bit of theory. I could describe My multi-language concept as a three-part, meaning it consists of three main parts (or aspects):

    1. Insert & differentiate multi-language content.
    2. Establish an automatic user-language detection.
    3. (Optional) Provide a toggle to switch languages by hand.

    Before I address each part, let Me tell You a little bit about the default language. The language which You set as a default one will be used automatically in following cases:

    1. If a guest of Your website use this language.
    2. If a guest of Your website use a language different than those included in Your multi-language mechanism.

    In this article I use English (US) as a default language - and a loose couple of others to illustrate various code snippets: RU (Russian), DE (German) and PL (Polish).


    So let's now discuss each aspect of the multi-language concept.


    1. Insert & differentiate multi-language content.
    This part is about providing a content for each language version - and differentiate all languages from each other. It is very simple: first think about things on Your website which You want to be available in another language(s) - maybe the UI elements, such as menu items, various labels, headers, short descriptions, and so on. It doesn't matter where those elements are placed code-wise - the only thing You need to do is to mark each element with a proper language .class - for example .us, .de, .fr, .ru, etc. Whatever element You want to translate, just assign a proper language class to it - and then clone (copy) that element, paste it next to the original one and change its language .class. Here are some examples of such an operation:

    From a Blogger template - a header available in three languages (a repeatable part in orange):

    <h2 class="us">full articles at hand</h2><h2 class="pl">pełne artykuły pod ręką</h2><h2 class="de">Vollständige Artikel zur Hand</h2>

    From a HTML/JavaScript gadget - the beginning of a longer line of jQuery code responsible for adding extra items to the main menu (here is a snippet covering one such an item):

    $("#PageList1 li:first").after("<li class='us'><a>current features</a></li><li class='pl'><a>funkcje programu</a></li><li class='ru'><a><b>строящийся сайт</b></a></li><li class='de'><a>Aktuelle Funktionen</a></li> ...................


    Besides translating various UI/layout elements You may need to include multi-language versions of Your posts/articles. In such a case the easiest way to handle this aspect of Your site may be to simply label them with the same name as in case of a proper language .classes mentioned earlier - but this time instead of inserting .classes directly into the template or the HTML/JavaScript gadget You will simply label articles via Blogger Dashboard or Open Live Writer (a Windows program with the help of which You can publish posts much easier and faster than using regular admin panel).

    So it will be enough if You just add a proper language label to each article.

    Now, back to jQuery code within HTML/JavaScript gadget (or elsewhere else - if You don't use Blogger) - You probably don't need to have language labels visible on Your website - so You can hide them all: just place this code on the top of Your whole jQuery set, right after those lines (see "Install jQuery on Your website" ):

    <script type="text/javascript">
    $(document).ready(function(){

    insert this:

    /* ----hide all language labels accompanying posts: */

    $(".post-labels a:contains('de'), .post-labels a:contains('pl'), .post-labels a:contains('ru'), .post-labels a:contains('us')").css({"display":"none"})

    Note the recurring pattern (the orange code), in which a single repeatable part is:

    .post-labels a:contains('xx')

    (xx = a single language .class), then a comma, a space and another instance of this same part. Each part for each language You want to include on Your website.

    In Blogger template ".post-labels a" refers to a single label belonging to label section accompanying each post.


    Now You can establish a code which will add a proper language .class to each post - according to what language labels they already have. Include all languages You want to handle - and again, note what is the repeatable pattern this time:

    /* ----Ascribing a language class to articles: */

    $(".post-body").has(".post-labels:contains('us')").addClass("us");

    $(".post-body").has(".post-labels:contains('pl')").addClass("pl");

    $(".post-body").has(".post-labels:contains('ru')").addClass("ru");

    $(".post-body").has(".post-labels:contains('de')").addClass("de");

    It is supposed to work this way: let's say You organize articles on Your website into a few sections: breakfast, dinner, dessert, vegan, etc. If an article belongs to vegan section - You label it with a "vegan" tag. If You want to have vegan articles available in other languages - You just add another labels to them, like "de", "fr", etc.

    Now, the menu of Your website consists of links to articles with particular labels - i.a. a vegan item, which will lead to all articles labeled by a vegan tag. Normally it would display a mixed bunch of vegan articles in various languages at once - but thanks to multi-language mechanism it will always display articles only in one particular language: the language Your guest uses, or the default one in case the mechanism won't recognize the user language.


    Now to ensure that proper articles will be displayed by default - below the code mentioned earlier on add those lines:

    $(".us").css({"display":"block"})
    $(".pl, .ru, .de").css({"display":"none"})

    In the first line use Your default language, in the second line include all the rest:


    The next step is to set the default language to all elements of Your website - by making it visible by default (while all the rest will be hidden). You'll do it in CSS, via simple code snippet like this - which will hide all non-default languages, leaving the default one visible. Therefore this time include all languages except the default one:

    /* ----hide all non-default languages: */
    .pl, .ru, .de { display: none; }

    If jQuery detects that a guest of Your website uses another language included in Your set - it will automatically switch to that one (which I'll discuss soon below).


    Now You have Your "language grid" done, the site will look virtually the same like before - and the language mechanism won't be fully working because You need to construct the actual code which will be operating on the language grid prepared before. You will do it with jQuery:


    2. Establish an automatic user-language detection.

    This step I've described here - I'd recommend You to read it first, because there are some interesting things worth knowing before You'll construct the final code.

    To summarize it, however, You need to know that in our case jQuery will detect a user language depends on what is their web-browser UI's one. I think we can assume that it is most likely that this UI language will correspond to the user's most preferred one.

    Each language has its own standardized, case-sensitive language tag.

    Note: don't confuse language tags with language .classes and labels mentioned earlier on. Language tags are standardized universal codes representing languages and their variants. They are cross-browsered, i.e. they should work fine regardless of what web-browser Your Guests use. But You must to use the exact form of those language tags in order for them to work right. Moreover, as I've mentioned before - it will be a good idea to include all possible variants of a particular language to make sure that it will be working in any situation. You'll use language tags only in automatic detection mechanism which detects a user language based on their web-browser one.

    Whereas language .classes and labels are of Your Own creation (named by You), which You'll use in all the rest of the jQuery/CSS code (as CSS .classes) - and also as Blogger posts/articles labels (which You can add via Blogger Dashboard or Open Live Writer).


    What is important is that some languages have multiple variants - and therefore multiple language tags, like - for example - German language includes several regions: Switzerland, Liechtenstein and Austria (de-CH, de-LI and de-AT accordingly, case-sensitive). Although people from all those regions will understand German - it is worth to establish a language detection for each variant to ensure that each of them in fact will switch the website to German (one (.de) language .class as a target for several German language tags listed above).

    Besides, sometimes a language may take a different language tag from a reason unknown to Me (like in case of Polish - which may take either pl or pl-PL language tag - or German with its de and de-DE tags). If You don't include this change, Your language mechanism may not work properly in some cases. I've described this issue here - where You'll find how to ensure Yourself whether a particular language takes always the same language tag or not.

    Once You gather all language tags You need, it's time to construct the automatic detection mechanism - which 1) will detect the user language - and then 2) - will switch Your website accordingly. The actual code template looks as follows:

    /* ----Detecting a guest's language (You don't need to include the default one) - start- */

    var userLang = navigator.language || navigator.userLanguage;

    if (userLang === "pl") {
    $(".us, .ru, .de").css({"display":"none"})
    $(".pl").css({"display":"block"})
    }

    /* ----Detecting a guest's language - end- */

    This time I showed You just one (orange) part which corresponds to a single language tag. Note that in the line

    if (userLang === "pl") {

    You use language tag - while all the rest of the orange part uses language .classes.

    So to make it work fully You need to copy the orange part, clone and edit it to cover all language tags You need. Once more, remember that some languages has more than one language tag.


    Congratulations, You've done it :) ! Now Your website should show itself in a user-language-dependent manner.


    3. (Optional) Provide a toggle to switch languages by hand.
    There are cases in which it could be good to switch languages by hand - alongside the automatic detection which could still take place. One example of such a situation when it could be useful is when You are working on a new project and need to often switch between languages to preview the content of the site, to compare the translations or some else purpose.

    In such cases You can add a language switch to Your mechanism. It has, however, one drawback: it doesn't remember a user choice after refreshing the site or loading another of its page. Maybe I'll improve this in the future, but now I don't know how to achieve it, especially without additional plug-ins.

    So let's talk about the code of the language switch. It needs a HTML base - I propose to use a HTML list to serve this purpose (let's call it #languages). Since it is a switch for all languages - include them all:

    <ul id="languages">

    <li><a>EN <img src='https://pathToTheFlagIcon.png' /></a></li>

    <li><a>RU <img src='https://pathToTheFlagIcon.png' /></a></li>

    <li><a>DE <img src='https://pathToTheFlagIcon.png' /></a></li>

    <li><a>PL <img src='https://pathToTheFlagIcon.png' /></a></li>

    </ul>

    Again an orange-colored part is a pattern here: a code snippet for a single language inside the switch.

    Visually a final form of this list will be icon-based, without any text - but I included uppercased texts in order for jQuery to target each language belonging to the switch. It could be done many other ways, it's just one of many. Since My language switch will display only icons - I add to the CSS:

    /* ----hide text inside the language switch: */

    #languages a
    { font-size: 0px; }

    Once You have the switch done, You need to write a jQuery code to handle it. A following code will be responsible for a single language - copy the orange part, then paste and edit it to define a code for each language of Your site, including the default one. Note that language .classes here are case-sensitive: uppercased refer to the text belonging to the language switch - lowercased are just Your language .classes' names.

    So the following code means that when a user clicks an item with Polish flag on the language switch - all elements of Your site which have language .class other than .pl will be hidden - while all the elements with .pl class will be visible:

    $("#languages li:contains(PL)").on("click", function() {
    $(".us, .ru, .de").css({"display":"none"})
    $(".pl").css({"display":"block"})
    });

    First line refers to the clicked text in a single item within language switch (#languages).

    Second line refers to all languages except the clicked one (those should be hidden).

    Third line refers to the language which should be visible.


    That's it - I hope that I did make this how-to easy enough for You to implement comfortably :) . In case of any questions feel free to use comments or contact form on this site :). Good luck!

    No comments:

    Post a Comment