「2023.002|EN」Issues Series: About Hexo and NexT Theme Multi-Language Support
New Requirements
My old blog used a single language en
, but published posts in two languages, and the two had no overlap. That is, the article was either Chinese or English.
I plan to publish each post in three languages, Chinese, Japanese and English, in this new blog, so I fiddled with the multi-language support of Hexo and NexT Theme, and here I record the problems encountered.
Features of Hexo and NexT Theme Multi-Language Support
Version
- "hexo": "6.3.0"
- "hexo-theme-next": "8.17.1"
Related Documents
- Hexo Docs/ Customization / Internationalization (i18n)
- NexT Docs / Theme Settings / i18n
Related Configuration
Refer to the official documents of Hexo and NexT Theme respectively to find the relevant configuration
Hexo
1 | language: |
NexT Theme
1 | # Show multilingual switcher in footer. |
Issues
Issue#1[Partially Solved]: Multi-language Support Not Working
I pointed out the problem I encountered when configuring multi-language support in the official document of NexT Theme:
the doc missed a necessary plugin hexo-generator-index-i18n, what's more, in my test you should also create a post with each language, or the related i18n_dir will not be generated. The latter may be a bug.
There are two problems here:
- The document does not mention that you must install a multi-language related plugin hexo-generator-index-i18n for multi-language support.
- You must publish posts in multiple languages, and the related multi-language folder
i18n_dir
will be created.
Let's discuss these two problems separately.
Missing hexo-generator-index-i18n Plugin
The solution is simple, just use the following command to install it:
1 | $ npm install hexo-generator-index-i18n --save |
i18n_dir and Post Article Association Problem
First, let's describe the problem in detail. Use the following command to view my blog source (Hexo) directory, as follows:
1 | (base) ➜ Blog tree pwnfan -L 1 |
Issue#2[Solved]: Multi-Language Post Assets Containing Issues
Expected Outcome
Post assets are resources that Hexo's posts need to reference, the most common of which are images.
If we follow the design concept of Hexo, when writing multi-language posts, we need to create multiple versions of the same blog post in different languages, such as:
1 | # default language is English |
At this time, the _posts directory structure is as follows:
1 | source/_posts |
In this case, if the article needs to reference pictures, it may encounter the following two situations:
- The same pictures are used for different language posts: the most common situation
- Some pictures used by different language posts may be different: less common, but occasionally there will be such requirements, such as the pictures we make contain text descriptions, and will be made according to the corresponding language version containing the corresponding language text description.
- Summarize this requirement: both exist the same assets (such as pictures), and also support language-related independent assets (such as pictures)
- This raises a question: how should the picture (Assets) folder be organized to meet the above requirements?
Issue Analysis && Relevant Information
We know that there are two ways to organize the Assets folder in Hexo:
- All posts share the same Assets folder, such as the images folder.
- Although this is the default way, I personally do not recommend it.
- When there are more articles, resources such as pictures are all included in the same folder. Although they can be distinguished by file name, it will still be very messy.
- Its advantage is that it can conveniently reuse assets previously added in different places such as post, but in fact in such blog applications, the reuse rate of assets is extremely low.
- Each post has its own assets folder.
- I prefer this way.
- Reference documents:
- Hexo Docs - Asset Folders
- Hexo Docs - Tag Plugins - Include Assets
- Specific setting method: set
post_asset_folder: true
in the Hexo configuration file_config.yml
. - This way also encounters problems when dealing with the above requirement "that is, there are both the same assets (such as pictures) and language-related independent assets (such as pictures)".
- You can crudely store the same pictures in the corresponding language assets folders, but there will be duplicate files which will waste disk space and remote git repository space.
After we set post_asset_folder: true
and add multi-language configuration, the folder structure is as follows:
1 | (base) ➜ pwnfan git:(dev) ✗ tree source/_posts |
Solution
To meet the requirement of "both existing assets (such as pictures) and language-related independent assets (such as pictures)", the following methods can be used:
As recommended in the previous section, set
post_asset_folder: true
in the Hexo configuration file_config.yml
.For the same assets: if the original post language is English, then translate it into Chinese post and Japanese post respectively. Then you can directly use the asset of the English post in the Chinese and Japanese posts to avoid the problem of storing duplicate files mentioned earlier.
- Here it needs to be specially explained that when referring to external assets in Chinese and Japanese posts, you cannot use relative paths, but need to use this "absolute path"
{% img /en/post/Issues-Series-About-Hexo-and-NexT-Theme-Multi-Language-Support/1.png "image title" %}
- The reason why the "absolute path" contains quotation marks is because it is not a real absolute path, but an absolute path based on the directory
{blog_source_folder}/public/
as the root directory.
- The reason why the "absolute path" contains quotation marks is because it is not a real absolute path, but an absolute path based on the directory
- Here it needs to be specially explained that when referring to external assets in Chinese and Japanese posts, you cannot use relative paths, but need to use this "absolute path"
Language-related independent assets: just put them in the corresponding language assets folder.
Issue#3 [Resolved]: Bug in NexT Theme when switching languages on different pages ⚠️
Issue Details
- Currently, when switching languages back and forth on different pages (home page, post, 404, tags, etc.) under the NexT Theme, there might be an issue where the switched page returns a 404 error.
Expected Outcome
- Home Page:
- Language switch should be available.
- The current NexT Theme already supports this type of language switching.
- Non-post Pages (about, 404, tags, etc.):
- The current NexT Theme returns a 404 error after switching to another language on these pages because it doesn't support customizing multiple languages for these types of pages, but the generated switch URL specifies a language, leading to this bug. To keep things simple, the expectation is to disable language switching or make it invalid on these pages.
- If users switch languages on these pages, even if we make the switch ineffective as described in the expected way, meaning keeping the URL unchanged, NexT's implementation mechanism will still trigger a page refresh. To achieve a no-refresh behavior, the required modifications are relatively complex. To keep things simple, we will leave it unchanged.
- Post Pages:
- Language switching should be allowed, and if there's no corresponding post in the chosen language, it should return a 404 error.
- The current NexT Theme doesn't handle custom permalink language conversion defined in the config very well. This is another bug that needs to be fixed.
Issue Analysis && Related Information
The reason for this problem is due to a bug in the NexT Theme when generating URLs for multiple languages. It fails to fully consider the current path, permalink format, and their relation to multiple languages.
The problematic code can be found at
1 | {%- if theme.language_switcher and languages.length > 1 %} |
i18n_path(language)
code:
100 | /** |
Solution
I attempted to solve this issue in my forked version with the following commit:
https://github.com/pwnfan/hexo-theme-next/commit/4a4ce6301ba5e0f7e05eea353c5c771e102dc8bb
I implemented and used a new function called i18n_path_pwnfan
. However, as the "Expected Outcome" section contains my personal subjective viewpoints and requirements, it might not be suitable for an official pull request. Therefore, I made the fix only in my own forked repository:
1 | {%- if theme.language_switcher and languages.length > 1 %} |
109 | /** |
Issue#4: How to Translate?
Please refer to another post 「2023.003/EN」Translate Hexo Articles efficiently using ChatGPT for reference.
Another Way to Support Multiple Languages in Hexo NexT Theme?
As we can see, the multi-language support and inclusion of Hexo and NexT Theme are:
- Multi-language support for basic elements of homepages, such as menus, etc.
- Multi-language posts
Another way I can think of to achieve multi-language posts indirectly is:
Set Hexo and NexT Theme to only one language, such as
en
Take advantage of the Tabs in the Tag Plugins exclusive to NexT Theme, which can indirectly realize multi-language. Refer to the following code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{% tabs Multiple Language Post Example %}
<!-- tab English -->
Where are you from?
<!-- endtab -->
<!-- tab 日本語 -->
ご出身地はどちらですか。
<!-- endtab -->
<!-- tab 中文 -->
你来自哪里?
<!-- endtab -->
{% endtabs %}The effect is as follows:
Where are you from?
ご出身地はどちらですか。
你来自哪里?
The problems with this approach are:
- No multi-language support for basic elements of homepages, such as menus, etc.
- There are two ways to organize Tags in posts (taking en/ja/zh-CN as an example)
- Only use 3 Tags in the post, each containing all the content in different languages
- Advantages: relatively simple and clear code
- Disadvantages
- Tabs have a fixed style frame, affecting the page style of the entire blog
- ToC generation has problems
- For each paragraph in the post, use independent 3 language Tags
- Advantages:
- ToC works normally
- Does not affect the overall page style of the blog
- Disadvantages:
- When there are many paragraphs in the article, a large number of Tags {% tabs %} need to be used, which is cumbersome and the code is not neat
- ToC can only use one language
- Advantages:
- Only use 3 Tags in the post, each containing all the content in different languages
Best Practice for Multi-Language Support for Technical Documents
The previous section records the attempts and thoughts made to meet my own needs for writing multi-language posts with Hexo and NexT Theme.
So which is the most elegant among the multi-language documents of technical documents I have seen so far? I wrote another article 「2023.004|EN」Best Practices Series: Multi-Language Support for Technical Documents to discuss this issue.