From b9c59c454d68e35708f64703a423930b99075cab Mon Sep 17 00:00:00 2001 From: Wu Cheng-Han Date: Fri, 19 Aug 2016 11:49:24 +0800 Subject: Add support of i18n with related patches and support "en" and "zh" locales for now --- app.js | 11 +++++ locales/en.json | 104 ++++++++++++++++++++++++++++++++++++++++ locales/zh.json | 104 ++++++++++++++++++++++++++++++++++++++++ package.json | 1 + public/css/cover.css | 4 ++ public/js/cover.js | 2 +- public/js/locale.js | 24 ++++++++++ public/views/body.ejs | 60 +++++++++++------------ public/views/header.ejs | 52 ++++++++++---------- public/views/help-modal.ejs | 76 ++++++++++++++--------------- public/views/index.ejs | 69 +++++++++++++------------- public/views/refresh-modal.ejs | 18 +++---- public/views/revision-modal.ejs | 8 ++-- public/views/signin-modal.ejs | 14 +++--- 14 files changed, 400 insertions(+), 147 deletions(-) create mode 100644 locales/en.json create mode 100644 locales/zh.json create mode 100644 public/js/locale.js diff --git a/app.js b/app.js index c0985761..04172b80 100644 --- a/app.js +++ b/app.js @@ -16,6 +16,7 @@ var formidable = require('formidable'); var morgan = require('morgan'); var passportSocketIo = require("passport.socketio"); var helmet = require('helmet'); +var i18n = require('i18n'); //core var config = require("./lib/config.js"); @@ -92,6 +93,16 @@ app.use(helmet.hsts({ preload: true })); +i18n.configure({ + locales: ['en', 'zh'], + cookie: 'locale', + directory: __dirname + '/locales' +}); + +app.use(cookieParser()); + +app.use(i18n.init); + // routes without sessions // static files app.use('/', express.static(__dirname + '/public', { maxAge: config.staticcachetime })); diff --git a/locales/en.json b/locales/en.json new file mode 100644 index 00000000..f1f0d140 --- /dev/null +++ b/locales/en.json @@ -0,0 +1,104 @@ +{ + "Collaborative markdown notes": "Collaborative markdown notes", + "Realtime collaborative markdown notes on all platforms.": "Realtime collaborative markdown notes on all platforms.", + "Best way to write and share your knowledge in markdown.": "Best way to write and share your knowledge in markdown.", + "Intro": "Intro", + "History": "History", + "New guest note": "New guest note", + "Collaborate with URL": "Collaborate with URL", + "Support charts and MathJax": "Support charts and MathJax", + "Support slide mode": "Support slide mode", + "Sign In": "Sign In", + "Below is the history from browser": "Below is the history from browser", + "Welcome!": "Welcome!", + "New note": "New note", + "or": "or", + "Sign Out": "Sign Out", + "Explore all features": "Explore all features", + "Select tags...": "Select tags...", + "Search keyword...": "Search keyword...", + "Sort by title": "Sort by title", + "Title": "Title", + "Sort by time": "Sort by time", + "Time": "Time", + "Export history": "Export history", + "Import history": "Import history", + "Clear history": "Clear history", + "Refresh history": "Refresh history", + "No history": "No history", + "Import from browser": "Import from browser", + "Releases": "Releases", + "Are you sure?": "Are you sure?", + "Cancel": "Cancel", + "Yes, do it!": "Yes, do it!", + "Choose method": "Choose method", + "Sign in via %s": "Sign in via %s", + "New": "New", + "Publish": "Publish", + "Extra": "Extra", + "Revision": "Revision", + "Slide Mode": "Slide Mode", + "Export": "Export", + "Import": "Import", + "Clipboard": "Clipboard", + "Download": "Download", + "Raw HTML": "Raw HTML", + "Edit": "Edit", + "View": "View", + "Both": "Both", + "Help": "Help", + "Upload Image": "Upload Image", + "Menu": "Menu", + "This page need refresh": "This page need refresh", + "You have an incompatible client version.": "You have an incompatible client version.", + "Refresh to update.": "Refresh to update.", + "New version available!": "New version available!", + "See releases notes here": "See releases notes here", + "Refresh to enjoy new features.": "Refresh to enjoy new features.", + "Your user state has changed.": "Your user state has changed.", + "Refresh to load new user state.": "Refresh to load new user state.", + "Refresh": "Refresh", + "Contacts": "Contacts", + "Report an issue": "Report an issue", + "Send us email": "Send us email", + "Documents": "Documents", + "Features": "Features", + "YAML Metadata": "YAML Metadata", + "Slide Example": "Slide Example", + "Cheatsheet": "Cheatsheet", + "Example": "Example", + "Syntax": "Syntax", + "Header": "Header", + "Unordered List": "Unordered List", + "Ordered List": "Ordered List", + "Todo List": "Todo List", + "Blockquote": "Blockquote", + "Bold font": "Bold font", + "Italics font": "Italics font", + "Strikethrough": "Strikethrough", + "Inserted text": "Inserted text", + "Marked text": "Marked text", + "Link": "Link", + "Image": "Image", + "Code": "Code", + "Externals": "Externals", + "This is a alert area.": "This is a alert area.", + "Revert": "Revert", + "Import from clipboard": "Import from clipboard", + "Paste your markdown or webpage here...": "Paste your markdown or webpage here...", + "Clear": "Clear", + "This note is locked": "This note is locked", + "Sorry, only owner can edit this note.": "Sorry, only owner can edit this note.", + "OK": "OK", + "Reach the limit": "Reach the limit", + "Sorry, you've reached the max length this note can be.": "Sorry, you've reached the max length this note can be.", + "Please reduce the content or divide it to more notes, thank you!": "Please reduce the content or divide it to more notes, thank you!", + "Import from Gist": "Import from Gist", + "Paste your gist url here...": "Paste your gist url here...", + "Import from Snippet": "Import from Snippet", + "Select From Available Projects": "Select From Available Projects", + "Select From Available Snippets": "Select From Available Snippets", + "OR": "OR", + "Export to Snippet": "Export to Snippet", + "Select Visibility Level": "Select Visibility Level" +} \ No newline at end of file diff --git a/locales/zh.json b/locales/zh.json new file mode 100644 index 00000000..a3bb7774 --- /dev/null +++ b/locales/zh.json @@ -0,0 +1,104 @@ +{ + "Collaborative markdown notes": "Markdown 協作筆記", + "Realtime collaborative markdown notes on all platforms.": "使用 Markdown 的跨平台即時協作筆記", + "Best way to write and share your knowledge in markdown.": "您使用 Markdown 寫作與分享知識的最佳方式", + "Intro": "簡介", + "History": "紀錄", + "New guest note": "建立訪客筆記", + "Collaborate with URL": "使用網址協作", + "Support charts and MathJax": "支援圖表與 MathJax", + "Support slide mode": "支援簡報模式", + "Sign In": "登入", + "Below is the history from browser": "以下為來自瀏覽器的紀錄", + "Welcome!": "歡迎!", + "New note": "建立筆記", + "or": "或", + "Sign Out": "登出", + "Explore all features": "探索所有功能", + "Select tags...": "選擇標籤...", + "Search keyword...": "搜尋關鍵字...", + "Sort by title": "用標題排序", + "Title": "標題", + "Sort by time": "用時間排序", + "Time": "時間", + "Export history": "匯出紀錄", + "Import history": "匯入紀錄", + "Clear history": "清空紀錄", + "Refresh history": "更新紀錄", + "No history": "沒有紀錄", + "Import from browser": "從瀏覽器匯入", + "Releases": "版本", + "Are you sure?": "你確定嗎?", + "Cancel": "取消", + "Yes, do it!": "沒錯,就這樣辦!", + "Choose method": "選擇方式", + "Sign in via %s": "透過 %s 登入", + "New": "新增", + "Publish": "發表", + "Extra": "增益", + "Revision": "修訂版本", + "Slide Mode": "簡報模式", + "Export": "匯出", + "Import": "匯入", + "Clipboard": "剪貼簿", + "Download": "下載", + "Raw HTML": "純 HTML", + "Edit": "編輯", + "View": "檢視", + "Both": "雙欄", + "Help": "協助", + "Upload Image": "上傳圖片", + "Menu": "選單", + "This page need refresh": "此頁面需要重新整理", + "You have an incompatible client version.": "您使用的是不相容的客戶端", + "Refresh to update.": "請重新整理來更新", + "New version available!": "新版本來了!", + "See releases notes here": "請由此查閱更新紀錄", + "Refresh to enjoy new features.": "請重新整理來享受最新功能", + "Your user state has changed.": "您的使用者狀態已變更", + "Refresh to load new user state.": "請重新整理來載入新的使用者狀態", + "Refresh": "重新整理", + "Contacts": "聯絡方式", + "Report an issue": "回報問題", + "Send us email": "寄信給我們", + "Documents": "文件", + "Features": "功能簡介", + "YAML Metadata": "YAML Metadata", + "Slide Example": "簡報範例", + "Cheatsheet": "快速簡表", + "Example": "範例", + "Syntax": "語法", + "Header": "標題", + "Unordered List": "無序清單", + "Ordered List": "有序清單", + "Todo List": "待辦事項", + "Blockquote": "引用", + "Bold font": "粗體", + "Italics font": "斜體", + "Strikethrough": "刪除線", + "Inserted text": "插入文字", + "Marked text": "標記文字", + "Link": "連結", + "Image": "圖片", + "Code": "程式碼", + "Externals": "外部", + "This is a alert area.": "這是警告區塊", + "Revert": "還原", + "Import from clipboard": "從剪貼簿匯入", + "Paste your markdown or webpage here...": "在這裡貼上 Markdown 或是網頁內容...", + "Clear": "清除", + "This note is locked": "此份筆記已被鎖定", + "Sorry, only owner can edit this note.": "抱歉,只有擁有者可以編輯此筆記", + "OK": "好的", + "Reach the limit": "到達上限", + "Sorry, you've reached the max length this note can be.": "抱歉,您已使用到此份筆記可用的最大長度", + "Please reduce the content or divide it to more notes, thank you!": "請減少內容或是將內容切成更多筆記,謝謝!", + "Import from Gist": "從 Gist 匯入", + "Paste your gist url here...": "在這裡貼上 gist 網址...", + "Import from Snippet": "從 Snippet 匯入", + "Select From Available Projects": "從可用的專案中選擇", + "Select From Available Snippets": "從可用的 Snippets 中選擇", + "OR": "或是", + "Export to Snippet": "匯出到 Snippet", + "Select Visibility Level": "選擇可見層級" +} \ No newline at end of file diff --git a/package.json b/package.json index 80042412..94b08eac 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "formidable": "^1.0.17", "helmet": "^2.1.2", "highlight.js": "^9.5.0", + "i18n": "^0.8.3", "imgur": "git+https://github.com/hackmdio/node-imgur.git", "jsdom-nogyp": "^0.8.3", "lz-string": "1.4.4", diff --git a/public/css/cover.css b/public/css/cover.css index bde3ec7c..ca0c6027 100644 --- a/public/css/cover.css +++ b/public/css/cover.css @@ -329,6 +329,10 @@ input { vertical-align: middle !important; } +select { + color: black; +} + @media (max-width: 768px) { span.ui-or { display: block; diff --git a/public/js/cover.js b/public/js/cover.js index c97bd256..f3533826 100644 --- a/public/js/cover.js +++ b/public/js/cover.js @@ -291,7 +291,7 @@ $(".ui-logout").click(function () { var filtertags = []; $(".ui-use-tags").select2({ - placeholder: 'Select tags...', + placeholder: $(".ui-use-tags").attr('placeholder'), multiple: true, data: function () { return { diff --git a/public/js/locale.js b/public/js/locale.js new file mode 100644 index 00000000..6fe7fdb6 --- /dev/null +++ b/public/js/locale.js @@ -0,0 +1,24 @@ +var lang = "en"; +var userLang = navigator.language || navigator.userLanguage; +var userLangCode = userLang.split('-')[0]; +var userCountryCode = userLang.split('-')[1]; +var locale = $('.ui-locale'); +var supportLangs = []; +$(".ui-locale option").each(function() { + supportLangs.push($(this).val()); +}); +if (Cookies.get('locale')) { + lang = Cookies.get('locale'); +} else if (supportLangs.indexOf(userLang) !== -1) { + lang = supportLangs[supportLangs.indexOf(userLang)]; +} else if (supportLangs.indexOf(userLangCode) !== -1) { + lang = supportLangs[supportLangs.indexOf(userLangCode)]; +} + +locale.val(lang); +locale.change(function() { + Cookies.set('locale', $(this).val(), { + expires: 365 + }); + window.location.reload(); +}); \ No newline at end of file diff --git a/public/views/body.ejs b/public/views/body.ejs index acf929ad..28680e49 100644 --- a/public/views/body.ejs +++ b/public/views/body.ejs @@ -43,15 +43,15 @@
OR
+<%= __('OR') %>
@@ -177,7 +177,7 @@