前言
因為求職需求,需要把網站轉換成英文,但是也想保留中文,開始尋找方法可以做中英文切換。
剛好看到 Hexo - Butterfly 官方網站 ,發現他們的網站就有中英文切換的功能,但是找遍了各個網站都沒有人說明。
所以只好看source code來了解是怎麼做的。
奮鬥了 2 天,終於找到方法了,以下是我整理的方法。
Step 1. 開設一個 private en repository
靈感主要參考上述連結,主要運作原理就是透過建立多個 GitHub Pages ,基本上會有一個專門運行中文的 repository,另外再開設一個專門運行英文的 repository,透過設定不同的 config.yml
和 _config.butterfly.yml
來達到中英文切換的效果。
以下是我建立的兩個 repository
建立特定語言的 GitHub Pages
Step 2. 設置 [en/zh] config
先用_config.yml
複製出兩個檔案分別是 config-en.yml
跟config-zh.yml
檔案,並且做以下設定。
config-en.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 language: en url: https://<url-url>/en root: /en/ source_dir: source-en public_dir: public-en include: exclude: ignore: - source/
config-zh.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 language: zh-TW url: https://shannonhung.github.io root: / source_dir: source public_dir: public include: exclude: ignore: - source-en/
Step 3. 設定 切換語言的 js
我是在這個btf.js 看到的,你可以在 source/self
中建立這個 btf.js
,內容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 (() => { const isIncludeEN = item => { const key = '/en/' return item.includes (key) } window .loadFullPage = (url ) => { window .location .href = url } const eventFn = (elements, includeEN ) => { elements.forEach (item => { if (!includeEN || !isIncludeEN (item.href )) { item.href = `javascript:loadFullPage('${item.href} ');` } }) } const nowIncludeEN = isIncludeEN (window .location .href ) const selector = nowIncludeEN ? document .querySelectorAll ('a[href^="https://<your-url>"]' ) : document .querySelectorAll ('a[href^="/en/"]' ) eventFn (selector, nowIncludeEN) })()
Step 4. 建立 source-en 資料夾
接下來很重要的一步,那就是把整個 source
資料夾複製,並且重新命名為 source-en
,並確認 btf.js
有在 source-en/self
中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 . ├── node_modules ├── scaffolds ├── source ├── source-en ├── themes ├── _config.butterfly.yml ├── _config.yml ├── config-butterfly-en.yml ├── config-en.yml ├── db.json ├── package-lock.json ├── package.json └── yarn.lock
Step 5. 建立 [en/zh] Butterfly config
請先複製你自己的 _config.butterfly.yml
,並且重新命名為 config-butterfly-en.yml
跟config-butterfly-zh.yml
,主要改動以下部分:
並設定 Butterfly config 需要引入剛剛建立的 btf.js
至不同的檔案
還有網站的目錄,你可以改成相對的語言目錄
config-butterfly-zh.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 menu: 找文章||fas fa-list: 目錄: /categories/ || fas fa-folder-open 標籤: /tags/ || fas fa-tags 文章: /archives/ || fas fa-archive 首頁: / || fas fa-home 關於我: /about/ || fas fa-heart 相關連結: /link/ || fas fa-link 語言||fas fa-language: English: /en/ || fas fa-e 中文: / || fas fa-c ... inject: bottom: - <script data-pjax src="/self/btf.js"></script>
config-butterfly-en.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 menu: Categroies: /categories/ || fas fa-folder-open Find Posts ||fas fa-list: By Tags: /tags/ || fas fa-tags By Posts: /archives/ || fas fa-archive Home Page: / || fas fa-home About Me: /about/ || fas fa-heart Links: /link/ || fas fa-link Language||fas fa-language: English: / || fas fa-e 中文: https://ShannonHung.github.io/ || fas fa-c ... inject: bottom: - <script data-pjax src="/en/self/btf.js"></script>
注意!!
config-butterfly-en.yml
中任何 /img/
圖片 或是 /self/
的 js 檔案,都要改成 /en/img/
或是 /en/self/
,這樣才能正確顯示圖片或是引入 js 檔案。
Step 6. 於 package.json 建立腳本
最後一步,就是更新 package.json
,讓他可以產生public-en
的資料夾,以便後續推到 repository en 中。
pcakage.json
1 2 3 4 5 6 7 8 9 ... "scripts" : { "push" : "hexo clean && hexo g && hexo douban && gulp && hexo deploy" , "show" : "hexo clean && hexo g && hexo s" , "update" : "git init && git add . && git commit -m 'backup' && git push origin main" , "kk" : "hexo clean && hexo g && hexo deploy" , "en" : "hexo clean && hexo g --config config-en.yml && hexo s --config config-en.yml" } , ...
Finally:腳本部署
現在我們準備建立腳本做部署,請先確認你有以下檔案:
config-butterfly-en.yml
config-butterfly-zh.yml
config-en.yml
config-zh.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 . ├── node_modules ├── public ├── public-en ├── scaffolds ├── source ├── source-en ├── themes ├── _config.butterfly.yml ├── _config.yml ├── config-butterfly-en.yml ├── config-butterfly-zh.yml ├── config-en.yml ├── config-zh.yml ├── db.json ├── package-lock.json ├── package.json └── yarn.lock
然後於跟目錄中建立一個 deploy.sh
,內容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 #!/bin/bash while [[ "$# " -gt 0 ]]; do case $1 in -h|--help ) echo "Usage: bash.sh [en|zh|all|show <en|zh>|-h]" echo "Options:" echo " [deploy|d] en Deploy English configuration to GitHub Pages" echo " [deploy|d] zh Deploy Chinese configuration to GitHub Pages" echo " [deploy|d] all Deploy both English and Chinese configurations to GitHub Pages" echo " [show|s] en Execute npm run show for English configuration" echo " [show|s] zh Execute npm run show for Chinese configuration" echo " -h, --help Display this help message" exit 0 ;; d | deploy) lang=$2 if [ "$lang " = "en" ] || [ "$lang " = "zh" ]; then cp "config-$lang .yml" _config.yml cp "config-butterfly-$lang .yml" "_config.butterfly.yml" npm run kk echo "Deploy $1 success!" elif [ "$lang " = "all" ]; then for lang_choice in "zh" "en" ; do cp "config-$lang_choice .yml" _config.yml cp "config-butterfly-$lang_choice .yml" "_config.butterfly.yml" npm run kk echo "Deploy $lang_choice success!" done else echo "Error! Please input 'en' or 'zh' or 'all'!" fi ;; s | show) lang=$2 if [ "$lang " = "en" ] || [ "$lang " = "zh" ]; then cp "config-$lang .yml" _config.yml cp "config-butterfly-$lang .yml" "_config.butterfly.yml" npm run show echo "Running npm show!" else echo "Error! Please use './bash.sh show en' or './bash.sh show zh'!" fi shift ;; *) echo "Error! Please input deploy <en|zh|all> or 'show <en|zh>' or '-h' for help!" exit 1 ;; esac shift done
記得把它改成可執行檔,然後可以透過以下指令進行部署囉:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 chmod +x deploy.sh./deploy.sh -h ./deploy.sh --help ./deploy.sh deploy en ./deploy.sh d en ./deploy.sh deploy zh ./deploy.sh d zh ./deploy.sh show en ./deploy.sh s en ./deploy.sh show zh ./deploy.sh s z
進階:不同文章切換中英文
如果你希望可以透過點擊 bottom 來達到中英文切換的效果如下:
那就繼續看下去吧!
Step1: 改寫 config-butterfly-<lang>.yml
config-butterfly-zh.yml
1 2 3 4 5 6 7 8 translate: enable: true default: 繁 defaultEncoding: 1
config-butterfly-.yml
1 2 3 4 5 6 7 8 translate: enable: true default: En defaultEncoding: 3
Step2. 撰寫 tw_en.js
檔案
接下來我們要寫一個 js 檔案,在任意一個頁面時,點擊 bottom 就可以切換中英文,邏輯是:
如果目前網站是:https://<rul>/en/posts/<post1>
當點擊 EN bottom 時,就會導向 https://<rul>/posts/<post1>
簡單來說就是把 /en
移除
如果目前網站是:https://<rul>/posts/<post1>
當點擊 EN bottom 時,就會導向 https://<rul>/en/posts/<post1>
簡單來說就是在第一個 /
後面加上 /en
因此我們把邏輯撰寫於 source/self/tw_en.js
與 source-en/self/tw_en.js
如下程式碼:
tw_en.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 document .addEventListener ("DOMContentLoaded" , function ( ) { const { defaultEncoding, translateDelay, msgToTraditionalChinese } = GLOBAL_CONFIG .translate ; const msgToEnglish = "EN" ; const snackbarData = GLOBAL_CONFIG .Snackbar ; let currentEncoding = defaultEncoding; const targetEncodingCookie = "translate-en-cht" ; let targetEncoding = saveToLocal.get (targetEncodingCookie) === undefined ? defaultEncoding : Number (saveToLocal.get ("translate-en-cht" )); let translateButtonObject; const isSnackbar = snackbarData !== undefined ; const isIncludeEN = (item ) => { const key = "/en/" ; return item.includes (key); }; const nowIncludeEN = isIncludeEN (window .location .href ); function translatePage ( ) { let currentUrl = window .location .href ; if (nowIncludeEN) { translateButtonObject.textContent = msgToTraditionalChinese; let newUrl = currentUrl.replace ("/en/" , "/" ); console .log (`Redirect to ${newUrl} ` ); window .location .href = newUrl; } else { translateButtonObject.textContent = msgToEnglish; let newUrl = currentUrl.replace (/^(https?:\/\/[^\/]+)(\/)?/ , "$1/en/" ); window .location .href = newUrl; } } function translateInitialization ( ) { translateButtonObject = document .getElementById ("translateLink" ); if (translateButtonObject) { if (nowIncludeEN) { translateButtonObject.textContent = msgToTraditionalChinese; } else { translateButtonObject.textContent = msgToEnglish; } } } document .addEventListener ("pjax:complete" , translateInitialization); window .translateFn = { translatePage, }; translateInitialization (); });
Step3. 設定 js 於 config 中
打開 config-butterfly-<lang>.yml
,並且設定 inject
如下:
config-butterfly-en.yml
1 2 3 4 5 6 inject: head: ... bottom: - <script data-pjax src="/en/self/btf.js"></script> - <script data-pjax src="/en/self/tw_en.js"></script>
config-butterfly-zh.yml
1 2 3 4 5 6 inject: head: ... bottom: - <script data-pjax src="/self/btf.js"></script> - <script data-pjax src="/self/tw_en.js"></script>