Bilingualism is cool, especially if I can achieve it on my blog. For me, a person who has been familiar with HTML and CSS, JavaScript is “the last part of a jigsaw puzzle”. So I started to learn JavaScript on Dec. 11th, 2021 by myself. After handling some basic knowledge, I came to writing my bilingualism module. At first, it only supports switching between Chinese and English. But now it can add infinity languages if I’m willing to.
My blog template Jekyll uses Django which does have i18n ability. But it is both powerful and difficult, which cannot be mastered by me in such a short time. So I give up.
Then I googled Jekyll i18n
and found several ways. One is not compatible with other Jekyll components (like Jekyll Multiple Languages Plugin), one is too old to use, one’s document is too vague for me to understand… So after struggling for about 6 hours, I was determined to use pure JavaScript to achieve my goal.
At first, I didn’t need a local preview environment, but I knew my blog can build one. But in order to see the result and speed up for development, I was forced to build one and overcome the difficulties. For example, my template needs some extra Jekyll components, so I need to run several extra installing codes, or it will feedback me an error. There was another error coming out because the Ruby’s version was too high. Then I uninstalled it and re-installed ver. 2.7.5. Damn it.
But, BUT! It was worth making a hard effort! This article means I made it. I’m so excited that I want to pat my paunch. Here are my thoughts.
Principle
The implementation principle is very simple and “rude”, which is traversal + string replacement, nothing else. But except replacement, there are still three important problems that need to be resolved:
- A global language switcher that is convenient, efficient, and comprehensible;
- Remember the user’s language setting and replace it automatically after refreshing and skipping the webpage;
- Use English hyperlinks for the English environment, or you will see Chinese articles (even relevant English ones exist) in the English environment.
How to traversal
I can’t make internationalization at basic code, so I have to do traversal. Many contents are generated dynamically and exist on many pages. So with a single JavaScript file can easily handle them.
There are many traversal ways. At first, I use HTML tags to match. Texts that need bilingual exist in <h2>
, <a>
, <li>
, etc. many types of tags, so the naming space of JavaScript becomes a mass. So how to fix this? Easy. Use <span class="keys"></span>
to contain bilingual texts, then with keys
class, I can manage all the bilingual texts. The declaration of variables is also simpler now.
Please notice that the traversal logic MUST runs after all HTML elements are loaded. So I use window.onload
to keep the bilingualism code waiting. After that, I built a function called replace
, which has only two variables (Chinese text and its relevant English text). It’s simple, which looks like replace("Bath, Songs, and Home", "浴沂咏归");
, easy to understand.
My friend told me that I can use a cover to block before everything loaded. So I used logic in this article and copied loading effect code from this article. Then in order to disable page scrolling, I used code from this article.
How to Build the Switcher
There is no doubt that the navigator bar will not change its position. It will stay on the left if the screen is wide enough, or it will stay on the top. So the switcher can be put on the top left side.
There are many switcher forms. Selector, checkbox, button group, etc.. I’m a rookie, so I choose hyperlink <a>
.
But it still needs to show which language was selected. When I chose Chinese, its hyperlink should become gray and can’t be clicked. In order to make this, I build a function called btnChange
for switching hyperlinks’ appearances. Now it can both indicate and switch.
Now I’ve used national flags to represent languages, easier to understand.
How to Remember Readers’ Language Settings
This is a common need. There is an attribute called window.localStorage
, which can store key-value pairs locally. I would say “I want you!” Then, refreshing and skipping won’t affect readers’ language settings.
When writing this article, I recalled that during the test, I’ve clicked the buttons countless times. That means I didn’t test the situation of empty language status! So, I opened a browser window in private mode. As I predicted, the switcher doesn’t become gray, they are both bright. So I cut if(!ls.lang){ls.lang = "cn";}
in it, let it default be Chinese. But, this is not friendly if the reader is not Chinese. So I reference this guide to know what the browser language is. For non-Chinese browsers, default English is nice!
How to Display English Articles (If Exist) in English Environment
For example, text in my About page will not be used again in another place. If I use text replacement will be very silly. So I write an extra about-en.md
, then I can use Markdown to format it, great.
The problem is, how to navigate the reader to the English About page. A link for English one in Chinese article or contrary is not a good idea.
So why not replace the website address? In the English environment, click the About button in the navigator area, you will see the English article. It is convenient but does not resolve the problem perfectly.
If I’m reading about-en
in the English environment, without processing, the website address will not change when I click the Chinese button. So I need to add an action: If the address point to a Chinese article in an English environment, make it point to an English one and jump.
Another thing is the contents in the <title>
tag. The principle is the same as above.
How to Make It More Scalable?
The former principle is to switch between two languages, which is not convenient.
So let’s change our minds. Let the code of Chinese to English stay there, but for switching from English to Chinese, I just change the language key and refresh the page. So the original text will display. Now I cut half of the replace
codes.
If I need to support the third language, that is easy. If now is English, I can initialize it to Chinese then switch to the target language. This means using Chinese as the “bridge” to all other languages. The code will be simple.
You Like This Module?
Here is an open-sourced simplified version developed by me. Please feel free to use it.