增加 wangEditor v4 的 国际化语言支持,support eng (#923)

* [il8] 增加html 编辑器的英文模式

* [template] add window.lang

* [wangeditor v4] 更新多语音

* [i18n] update eng langure

* [i18n] update eng langure

* update releaseBook langure

---------

Co-authored-by: admin <you@example.com>
pull/926/head
ydf 2024-01-05 10:45:07 +08:00 committed by GitHub
parent 663eb28de2
commit e64bee1e1e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 169 additions and 41 deletions

2
.gitignore vendored
View File

@ -2,7 +2,7 @@
*.o *.o
*.a *.a
*.so *.so
.DS_Store
# Folders # Folders
_obj _obj
_test _test

View File

@ -136,4 +136,4 @@ ENTRYPOINT ["/bin/bash", "/mindoc/start.sh"]
# https://docs.docker.com/engine/reference/commandline/run/#options # https://docs.docker.com/engine/reference/commandline/run/#options
# set MINDOC=//d/mindoc # windows # set MINDOC=//d/mindoc # windows
# export MINDOC=/home/ubuntu/mindoc-docker # linux # export MINDOC=/home/ubuntu/mindoc-docker # linux
# docker run --rm -it -p 8181:8181 -v "%MINDOC%":"/mindoc-sync-host" --name mindoc -e MINDOC_ENABLE_EXPORT=true -d gsw945/mindoc:2.1 # docker run -d --name=mindoc --restart=always -v /www/mindoc/uploads:/mindoc/uploads -v /www/mindoc/database:/mindoc/database -v /www/mindoc/conf:/mindoc/conf -e MINDOC_DB_ADAPTER=sqlite3 -e MINDOC_DB_DATABASE=./database/mindoc.db -e MINDOC_CACHE=true -e MINDOC_CACHE_PROVIDER=file -p 8181:8181 mindoc-org/mindoc:v2.1

View File

@ -447,6 +447,14 @@ function initHighlighting() {
} }
$(function () { $(function () {
locales = {
'zh-CN': {
attachments: ' ',
},
'en': {
attachments: ' attachments',
}
}
window.vueApp = new Vue({ window.vueApp = new Vue({
el: "#attachList", el: "#attachList",
data: { data: {
@ -484,7 +492,7 @@ $(function () {
}, },
watch: { watch: {
lists: function ($lists) { lists: function ($lists) {
$("#attachInfo").text(" " + $lists.length + " 个附件") $("#attachInfo").text(" " + $lists.length + locales[lang].attachments)
} }
} }
}); });

View File

@ -46,6 +46,12 @@ $(function () {
console.warn('You could only upload images.'); console.warn('You could only upload images.');
} }
}; };
editor.config.lang = window.lang;
editor.i18next = window.i18next;
editor.config.languages['en']['wangEditor']['menus']['title'][''] = 'save';
editor.config.languages['en']['wangEditor']['menus']['title'][''] = 'publish';
editor.config.languages['en']['wangEditor']['menus']['title'][''] = 'attachment';
editor.config.languages['en']['wangEditor']['menus']['title']['history'] = 'history';
/* /*
editor.config.menus.splice(0,0,"|"); editor.config.menus.splice(0,0,"|");
editor.config.menus.splice(0,0,"history"); editor.config.menus.splice(0,0,"history");
@ -80,6 +86,57 @@ $(function () {
}; };
*/ */
window.editormdLocales = {
'zh-CN': {
placeholder: ' Markdown ',
contentUnsaved: '',
noDocNeedPublish: '',
loadDocFailed: '',
fetchDocFailed: '',
cannotAddToEmptyNode: '',
overrideModified: '',
confirm: '',
cancel: '',
contentsNameEmpty: '',
addDoc: '',
edit: '',
delete: '',
loadFailed: '',
tplNameEmpty: '',
tplContentEmpty: '',
saveSucc: '',
serverExcept: '',
paramName: '',
paramType: '',
example: '',
remark: '',
},
'en': {
placeholder: 'This editor supports Markdown editing, writing on the left and previewing on the right.',
contentUnsaved: 'The edited content is not saved, need to save it?',
noDocNeedPublish: 'No Document need to be publish',
loadDocFailed: 'Load Document failed',
fetchDocFailed: 'Fetch Document info failed',
cannotAddToEmptyNode: 'Cannot add content to empty node',
overrideModified: 'The document has been modified by someone else, are you sure to overwrite the document?',
confirm: 'Confirm',
cancel: 'Cancel',
contentsNameEmpty: 'Document Name cannot be empty',
addDoc: 'Add Document',
edit: 'Edit',
delete: 'Delete',
loadFailed: 'Failed to load, please try again',
tplNameEmpty: 'Template name cannot be empty',
tplContentEmpty: 'Template content cannot be empty',
saveSucc: 'Save success',
serverExcept: 'Server Exception',
paramName: 'Parameter',
paramType: 'Type',
example: 'Example',
remark: 'Remark',
}
};
window.editor.config.onchange = function (newHtml) { window.editor.config.onchange = function (newHtml) {
var saveMenu = window.editor.menus.menuList.find((item) => item.key == 'save'); var saveMenu = window.editor.menus.menuList.find((item) => item.key == 'save');
// 判断内容是否改变 // 判断内容是否改变
@ -150,8 +207,8 @@ $(function () {
} }
var version = ""; var version = "";
if(!node){ if (!node) {
layer.msg("获取当前文档信息失败"); layer.msg(editormdLocales[lang].fetchDocFailed);
return; return;
} }
var doc_id = parseInt(node.id); var doc_id = parseInt(node.id);
@ -191,9 +248,9 @@ $(function () {
callback(); callback();
} }
}else if(res.errcode === 6005){ }else if(res.errcode === 6005){
var confirmIndex = layer.confirm('', { var confirmIndex = layer.confirm(editormdLocales[lang].overrideModified, {
btn: ['',''] //按钮 btn: [editormdLocales[lang].confirm, editormdLocales[lang].cancel] // 按钮
}, function(){ }, function () {
layer.close(confirmIndex); layer.close(confirmIndex);
saveDocument(true,callback); saveDocument(true,callback);
}); });
@ -205,6 +262,7 @@ $(function () {
} }
/** /**
* *
*/ */
@ -265,7 +323,7 @@ $(function () {
"separator_before": false, "separator_before": false,
"separator_after": true, "separator_after": true,
"_disabled": false, "_disabled": false,
"label": "添加文档", "label": window.editormdLocales[window.lang].addDoc,//"添加文档",
"icon": "fa fa-plus", "icon": "fa fa-plus",
"action": function (data) { "action": function (data) {
@ -279,7 +337,7 @@ $(function () {
"separator_before": false, "separator_before": false,
"separator_after": true, "separator_after": true,
"_disabled": false, "_disabled": false,
"label": "编辑", "label": window.editormdLocales[window.lang].edit,
"icon": "fa fa-edit", "icon": "fa fa-edit",
"action": function (data) { "action": function (data) {
var inst = $.jstree.reference(data.reference); var inst = $.jstree.reference(data.reference);
@ -291,7 +349,7 @@ $(function () {
"separator_before": false, "separator_before": false,
"separator_after": true, "separator_after": true,
"_disabled": false, "_disabled": false,
"label": "删除", "label": window.editormdLocales[window.lang].delete,
"icon": "fa fa-trash-o", "icon": "fa fa-trash-o",
"action": function (data) { "action": function (data) {
var inst = $.jstree.reference(data.reference); var inst = $.jstree.reference(data.reference);
@ -305,7 +363,7 @@ $(function () {
window.treeCatalog = $(this).jstree(); window.treeCatalog = $(this).jstree();
}).on('select_node.jstree', function (node, selected, event) { }).on('select_node.jstree', function (node, selected, event) {
if(window.editor.menus.menuList.find((item) => item.key == 'save').$elem.hasClass('selected')) { if(window.editor.menus.menuList.find((item) => item.key == 'save').$elem.hasClass('selected')) {
if(confirm("编辑内容未保存,需要保存吗?")){ if (confirm(window.editormdLocales[window.lang].contentUnsaved)) {
saveDocument(false,function () { saveDocument(false,function () {
loadDocument(selected); loadDocument(selected);
}); });
@ -321,25 +379,33 @@ $(function () {
window.releaseBook = function () { window.releaseBook = function () {
if(Object.prototype.toString.call(window.documentCategory) === '[object Array]' && window.documentCategory.length > 0){ if(Object.prototype.toString.call(window.documentCategory) === '[object Array]' && window.documentCategory.length > 0){
if(window.editor.menus.menuList.find((item) => item.key == 'save').$elem.hasClass('selected')) { if(window.editor.menus.menuList.find((item) => item.key == 'save').$elem.hasClass('selected')) {
if(confirm("编辑内容未保存,需要保存吗?")) { if(confirm(editormdLocales[lang].contentUnsaved)) {
saveDocument(); saveDocument();
} }
} }
locales = {
'zh-CN': {
publishToQueue: '',
},
'en': {
publishToQueue: 'The publish task has been pushed to the queue</br> and will be executed soon.',
}
}
$.ajax({ $.ajax({
url : window.releaseURL, url: window.releaseURL,
data :{"identify" : window.book.identify }, data: {"identify": window.book.identify},
type : "post", type: "post",
dataType : "json", dataType: "json",
success : function (res) { success: function (res) {
if(res.errcode === 0){ if (res.errcode === 0) {
layer.msg("发布任务已推送到任务队列,稍后将在后台执行。"); layer.msg(locales[lang].publishToQueue);
}else{ } else {
layer.msg(res.message); layer.msg(res.message);
} }
} }
}); });
}else{ }else{
layer.msg("没有需要发布的文档") layer.msg(editormdLocales[lang].noDocNeedPublish)
} }
}; };

View File

@ -1,4 +1,54 @@
$(function () { $(function () {
window.editormdLocales = {
'zh-CN': {
placeholder: ' Markdown ',
contentUnsaved: '',
noDocNeedPublish: '',
loadDocFailed: '',
fetchDocFailed: '',
cannotAddToEmptyNode: '',
overrideModified: '',
confirm: '',
cancel: '',
contentsNameEmpty: '',
addDoc: '',
edit: '',
delete: '',
loadFailed: '',
tplNameEmpty: '',
tplContentEmpty: '',
saveSucc: '',
serverExcept: '',
paramName: '',
paramType: '',
example: '',
remark: '',
},
'en': {
placeholder: 'This editor supports Markdown editing, writing on the left and previewing on the right.',
contentUnsaved: 'The edited content is not saved, need to save it?',
noDocNeedPublish: 'No Document need to be publish',
loadDocFailed: 'Load Document failed',
fetchDocFailed: 'Fetch Document info failed',
cannotAddToEmptyNode: 'Cannot add content to empty node',
overrideModified: 'The document has been modified by someone else, are you sure to overwrite the document?',
confirm: 'Confirm',
cancel: 'Cancel',
contentsNameEmpty: 'Document Name cannot be empty',
addDoc: 'Add Document',
edit: 'Edit',
delete: 'Delete',
loadFailed: 'Failed to load, please try again',
tplNameEmpty: 'Template name cannot be empty',
tplContentEmpty: 'Template content cannot be empty',
saveSucc: 'Save success',
serverExcept: 'Server Exception',
paramName: 'Parameter',
paramType: 'Type',
example: 'Example',
remark: 'Remark',
}
};
window.addDocumentModalFormHtml = $(this).find("form").html(); window.addDocumentModalFormHtml = $(this).find("form").html();
window.menu_save = $("#markdown-save"); window.menu_save = $("#markdown-save");
window.uploader = null; window.uploader = null;
@ -286,7 +336,7 @@ $(function () {
"separator_before": false, "separator_before": false,
"separator_after": true, "separator_after": true,
"_disabled": false, "_disabled": false,
"label": "添加文档", "label": window.editormdLocales[window.lang].addDoc,//"添加文档",
"icon": "fa fa-plus", "icon": "fa fa-plus",
"action": function (data) { "action": function (data) {
@ -300,7 +350,7 @@ $(function () {
"separator_before": false, "separator_before": false,
"separator_after": true, "separator_after": true,
"_disabled": false, "_disabled": false,
"label": "编辑", "label": window.editormdLocales[window.lang].edit,
"icon": "fa fa-edit", "icon": "fa fa-edit",
"action": function (data) { "action": function (data) {
var inst = $.jstree.reference(data.reference); var inst = $.jstree.reference(data.reference);
@ -312,7 +362,7 @@ $(function () {
"separator_before": false, "separator_before": false,
"separator_after": true, "separator_after": true,
"_disabled": false, "_disabled": false,
"label": "删除", "label": window.editormdLocales[window.lang].delete,
"icon": "fa fa-trash-o", "icon": "fa fa-trash-o",
"action": function (data) { "action": function (data) {
var inst = $.jstree.reference(data.reference); var inst = $.jstree.reference(data.reference);
@ -329,7 +379,7 @@ $(function () {
}).on('select_node.jstree', function (node, selected, event) { }).on('select_node.jstree', function (node, selected, event) {
if(window.menu_save.hasClass('change')) { if(window.menu_save.hasClass('change')) {
if(confirm("编辑内容未保存,需要保存吗?")){ if (confirm(window.editormdLocales[window.lang].contentUnsaved)) {
saveDocument(false,function () { saveDocument(false,function () {
loadDocument(selected); loadDocument(selected);
}); });
@ -344,6 +394,7 @@ $(function () {
window.editor.root.innerHTML =''; window.editor.root.innerHTML ='';
}); });
window.saveDocument = saveDocument; window.saveDocument = saveDocument;
window.releaseBook = function () { window.releaseBook = function () {

View File

@ -5,7 +5,7 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<title>编辑文档 - Powered by MinDoc</title> <title>{{i18n .Lang "doc.edit_doc"}} - Powered by MinDoc</title>
<style type="text/css"> <style type="text/css">
.w-e-menu.selected > i { .w-e-menu.selected > i {
color: #44B036 !important; color: #44B036 !important;
@ -30,6 +30,7 @@
window.historyURL = "{{urlfor "DocumentController.History"}}"; window.historyURL = "{{urlfor "DocumentController.History"}}";
window.removeAttachURL = "{{urlfor "DocumentController.RemoveAttachment"}}"; window.removeAttachURL = "{{urlfor "DocumentController.RemoveAttachment"}}";
window.vueApp = null; window.vueApp = null;
window.lang = {{i18n $.Lang "common.js_lang"}};
</script> </script>
<!-- Bootstrap --> <!-- Bootstrap -->
<link href="{{cdncss "/static/bootstrap/css/bootstrap.min.css"}}" rel="stylesheet"> <link href="{{cdncss "/static/bootstrap/css/bootstrap.min.css"}}" rel="stylesheet">
@ -54,21 +55,21 @@
<div class="m-manual manual-editor"> <div class="m-manual manual-editor">
<!--{{/*<div class="manual-head" id="editormd-tools"> <!--{{/*<div class="manual-head" id="editormd-tools">
<div class="editormd-group"> <div class="editormd-group">
<a href="{{urlfor "BookController.Dashboard" ":key" .Model.Identify}}" data-toggle="tooltip" data-title="返回"><i class="fa fa-chevron-left" aria-hidden="true"></i></a> <a href="{{urlfor "BookController.Dashboard" ":key" .Model.Identify}}" data-toggle="tooltip" data-title="{{i18n .Lang "doc.backward"}}"><i class="fa fa-chevron-left" aria-hidden="true"></i></a>
</div> </div>
<div class="editormd-group"> <div class="editormd-group">
<a href="javascript:;" id="markdown-save" data-toggle="tooltip" data-title="保存" class="disabled save"><i class="fa fa-save" aria-hidden="true" name="save"></i></a> <a href="javascript:;" id="markdown-save" data-toggle="tooltip" data-title="{{i18n .Lang "doc.save"}}" class="disabled save"><i class="fa fa-save" aria-hidden="true" name="save"></i></a>
</div> </div>
<div class="editormd-group"> <div class="editormd-group">
<a href="javascript:;" data-toggle="tooltip" data-title="修改历史"><i class="fa fa-history item" name="history" aria-hidden="true"></i></a> <a href="javascript:;" data-toggle="tooltip" data-title="{{i18n .Lang "doc.modify_history"}}"><i class="fa fa-history item" name="history" aria-hidden="true"></i></a>
<a href="javascript:;" data-toggle="tooltip" data-title="边栏"><i class="fa fa-columns item" aria-hidden="true" name="sidebar"></i></a> <a href="javascript:;" data-toggle="tooltip" data-title="{{i18n .Lang "doc.sidebar"}}"><i class="fa fa-columns item" aria-hidden="true" name="sidebar"></i></a>
<a href="javascript:;" data-toggle="tooltip" data-title="使用帮助"><i class="fa fa-question-circle-o last" aria-hidden="true" name="help"></i></a> <a href="javascript:;" data-toggle="tooltip" data-title="{{i18n .Lang "doc.help"}}"><i class="fa fa-question-circle-o last" aria-hidden="true" name="help"></i></a>
</div> </div>
<div class="editormd-group"> <div class="editormd-group">
<a href="javascript:;" data-toggle="tooltip" data-title="发布"><i class="fa fa-cloud-upload" name="release" aria-hidden="true"></i></a> <a href="javascript:;" data-toggle="tooltip" data-title="{{i18n .Lang "doc.publish"}}"><i class="fa fa-cloud-upload" name="release" aria-hidden="true"></i></a>
</div> </div>
<div class="editormd-group"> <div class="editormd-group">
@ -81,8 +82,8 @@
<div class="manual-body"> <div class="manual-body">
<div class="manual-category" id="manualCategory" style="top: 0;"> <div class="manual-category" id="manualCategory" style="top: 0;">
<div class="manual-nav"> <div class="manual-nav">
<div class="nav-item active"><i class="fa fa-bars" aria-hidden="true"></i> 文档</div> <div class="nav-item active"><i class="fa fa-bars" aria-hidden="true"></i> {{i18n .Lang "doc.document"}}</div>
<div class="nav-plus pull-right" data-toggle="tooltip" data-title="返回" data-direction="right"> <div class="nav-plus pull-right" data-toggle="tooltip" data-title="{{i18n .Lang "doc.backward"}}" data-direction="right">
<a style="color: #999999;" href="{{urlfor "BookController.Dashboard" ":key" .Model.Identify}}" target="_blank"><i class="fa fa-chevron-left" aria-hidden="true"></i></a> <a style="color: #999999;" href="{{urlfor "BookController.Dashboard" ":key" .Model.Identify}}" target="_blank"><i class="fa fa-chevron-left" aria-hidden="true"></i></a>
</div> </div>
<div class="nav-plus pull-right" id="btnAddDocument" data-toggle="tooltip" data-title="{{i18n .Lang "doc.create_doc"}}" data-direction="right"><i class="fa fa-plus" aria-hidden="true"></i></div> <div class="nav-plus pull-right" id="btnAddDocument" data-toggle="tooltip" data-title="{{i18n .Lang "doc.create_doc"}}" data-direction="right"><i class="fa fa-plus" aria-hidden="true"></i></div>
@ -97,7 +98,7 @@
<div id="htmlEditor" class="manual-editormd-active" style="height: 100%"></div> <div id="htmlEditor" class="manual-editormd-active" style="height: 100%"></div>
</div> </div>
<div class="manual-editor-status"> <div class="manual-editor-status">
<div id="attachInfo" class="item" style="display: inline-block; padding: 0 3em;">0 个附件</div> <div id="attachInfo" class="item" style="display: inline-block; padding: 0 3em;">0 {{i18n .Lang "doc.attachments"}}</div>
</div> </div>
</div> </div>
@ -150,7 +151,7 @@
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button> <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title" id="myModalLabel">上传附件</h4> <h4 class="modal-title" id="myModalLabel">{{i18n .Lang "doc.upload_attachment"}}</h4>
</div> </div>
<div class="modal-body"> <div class="modal-body">
<div class="attach-drop-panel"> <div class="attach-drop-panel">
@ -187,14 +188,15 @@
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<span id="add-error-message" class="error-message"></span> <span id="add-error-message" class="error-message"></span>
<button type="button" class="btn btn-default" data-dismiss="modal">取消</button> <button type="button" class="btn btn-default" data-dismiss="modal">{{i18n .Lang "common.cancel"}}</button>
<button type="button" class="btn btn-primary" id="btnUploadAttachFile" data-dismiss="modal">确定</button> <button type="button" class="btn btn-primary" id="btnUploadAttachFile" data-dismiss="modal">{{i18n .Lang "common.confirm"}}</button>
</div> </div>
</div> </div>
</form> </form>
</div> </div>
</div> </div>
<script src="https://cdn.jsdelivr.net/npm/i18next/i18next.min.js"></script>
<script src="{{cdnjs "/static/jquery/1.12.4/jquery.min.js"}}"></script> <script src="{{cdnjs "/static/jquery/1.12.4/jquery.min.js"}}"></script>
<script src="{{cdnjs "/static/bootstrap/js/bootstrap.min.js"}}"></script> <script src="{{cdnjs "/static/bootstrap/js/bootstrap.min.js"}}"></script>
<script src="{{cdnjs "/static/vuejs/vue.min.js"}}" type="text/javascript"></script> <script src="{{cdnjs "/static/vuejs/vue.min.js"}}" type="text/javascript"></script>
@ -243,7 +245,7 @@
attachment_id : file.id, attachment_id : file.id,
file_size : file.size, file_size : file.size,
file_name : file.name, file_name : file.name,
message : "正在上传" message : "{{i18n .Lang "doc.uploading"}}"
}; };
window.vueApp.lists.splice(0,0,item); window.vueApp.lists.splice(0,0,item);
@ -252,7 +254,7 @@
var item = window.vueApp.lists[i]; var item = window.vueApp.lists[i];
if(item.attachment_id == file.id){ if(item.attachment_id == file.id){
item.state = "error"; item.state = "error";
item.message = "上传失败"; item.message = "{{i18n .Lang "message.upload_failed"}}:" + reason;
break; break;
} }
} }

View File

@ -24,6 +24,7 @@
window.historyURL = "{{urlfor "DocumentController.History"}}"; window.historyURL = "{{urlfor "DocumentController.History"}}";
window.removeAttachURL = "{{urlfor "DocumentController.RemoveAttachment"}}"; window.removeAttachURL = "{{urlfor "DocumentController.RemoveAttachment"}}";
window.highlightStyle = "{{.HighlightStyle}}"; window.highlightStyle = "{{.HighlightStyle}}";
window.lang = {{i18n $.Lang "common.js_lang"}};
</script> </script>
<!-- Bootstrap --> <!-- Bootstrap -->
<link href="{{cdncss "/static/bootstrap/css/bootstrap.min.css"}}" rel="stylesheet"> <link href="{{cdncss "/static/bootstrap/css/bootstrap.min.css"}}" rel="stylesheet">