hexojs / hexo

A fast, simple & powerful blog framework, powered by Node.js.
https://hexo.io
MIT License
39.53k stars 4.86k forks source link

Multilingual(i18n) Page + Post Support #4701

Open ilharp opened 3 years ago

ilharp commented 3 years ago

Check List


I've been searching on the "Best Practice" of Hexo's Multitilingual (i18n) feature in recent days, and here are some of the results I've got so far, with detailed usages of each feature.

Multilingual Support for Pages

For built-in pages like archive and category, I chose hexo-generator-i18n. It performs well.

For custom pages, the best way is to place files in different language-identifier folders under the source folder, excluding default language. Here's an example tree:

├─about
│      index.md
│
├─zh-CN
│  └─about
│          index.md

The reason for this is that most language-switcher components will roll back to the normal path (which does not contain language-ids) when switching to default languages, such as theme-next:

return this.url_for(`${this.languages.indexOf(language) === 0 ? '' : '/' + language}/${base}`);

For config like this:

language:
  - en
  - zh-CN

This will change path from /zh-CN/about/ to /about/.

Multilingual Support for Posts

For posts, the best way is to place files in different language-identifier folders (same as custom pages) under _posts folder, including default language. Here's an example tree:

├─en
│  └─common
│          index.md
│
├─zh-CN
│   └─common
│           index.md

Then, set config like this:

language:
  - en # Default language
  - zh-CN
i18n_dir: :lang
i18n: # hexo-generator-i18n settings
  type:
    - page
    # - post # Disable direct copy
  generator:
    - archive
    - category
    - tag
    - index

permalink_defaults:
  lang: en
permalink: :lang/:title/
new_post_name: :lang/:title.md

And you can see your posts in different languages in /en/my-post/ and /zh-CN/my-post/.

The reason we need to place all posts in language folder is, the i18n_dir use permalink to resolve language info, and the permalink use new_post_name to resolve page meta. I'm also confused about this, but that's really what I tested. If you don't configure like this, you may find something strange with the generated path and page info.

So I forked hexo-theme-next and made some changes on the language-switcher. It now looks like this:

/**
 * Get page path given a certain language tag
 */
hexo.extend.helper.register('i18n_path', function(language) {
  const { path, lang, layout } = this.page;
  const base = path.startsWith(lang) ? path.slice(lang.length + 1) : path;
  return this.url_for(`${this.languages.indexOf(language) === 0 && layout !== 'post' ? '' : '/' + language}/${base}`);
});

It will rollback to default path without language only when layout !== 'post'. This performs well when testing.


And there are still some small issues:


Hope that Hexo will eventually be able to fully support i18n for all pages.

stevenjoezhang commented 3 years ago

FYI, hexo-theme-minos overrides the default hexo plugin to implement multilingual support for index / archive / tag generator: https://github.com/ppoffice/hexo-theme-minos/blob/master/scripts/10_i18n.js

See also https://github.com/hexojs/hexo/issues/1125#issuecomment-595583413

dimaslanjaka commented 1 year ago

I created simple hexo site with support multi language for post/pages/archives based on hexo-theme-minos, but ongoing language switcher and meta seo.

https://github.com/dimaslanjaka/hexo-multi-language

http://www.webmanajemen.com/hexo-multi-language/ http://www.webmanajemen.com/hexo-multi-language/id/Hello-World.html http://www.webmanajemen.com/hexo-multi-language/en/Hello-World.html

rirufa commented 1 year ago

I add support multi language for adding page. It run "hexo new page text-x", it make pages each language folder.

https://github.com/rirufa/website-template/blob/main/themes/singleline/scripts/i18n.js