]> BookStack Code Mirror - bookstack/commitdiff
Made WYSIWYG editor translatable
authorDan Brown <redacted>
Sun, 6 Feb 2022 21:17:08 +0000 (21:17 +0000)
committerDan Brown <redacted>
Sun, 6 Feb 2022 21:17:08 +0000 (21:17 +0000)
- Created new translation file for editor view.
- Added simple logic to format for tinymce.
- Aligned some of the custom labels we were using.

resources/js/components/wysiwyg-editor.js
resources/js/wysiwyg/config.js
resources/js/wysiwyg/plugin-codeeditor.js
resources/js/wysiwyg/plugin-drawio.js
resources/js/wysiwyg/plugins-customhr.js
resources/js/wysiwyg/plugins-imagemanager.js
resources/lang/en/editor.php [new file with mode: 0644]
resources/views/pages/parts/editor-translations.blade.php [new file with mode: 0644]
resources/views/pages/parts/wysiwyg-editor.blade.php

index f6ecb368a3df116973b321141538446f1c57bf68..446f2ca4938696e6538774fa8357419f727b72c0 100644 (file)
@@ -10,6 +10,7 @@ class WysiwygEditor {
         this.isDarkMode = document.documentElement.classList.contains('dark-mode');
 
         this.tinyMceConfig = buildEditorConfig({
+            language: this.$opts.language,
             containerElement: this.elem,
             darkMode: this.isDarkMode,
             textDirection: this.textDirection,
@@ -18,7 +19,8 @@ class WysiwygEditor {
             translations: {
                 imageUploadErrorText: this.$opts.imageUploadErrorText,
                 serverUploadLimitText: this.$opts.serverUploadLimitText,
-            }
+            },
+            translationMap: window.editor_translations,
         });
 
         window.$events.emitPublic(this.elem, 'editor-tinymce::pre-init', {config: this.tinyMceConfig});
index e1f2fb6e5880ed414683acd57613e7fb97e16f92..1594646d8918d62cc6ed644edc5bb60dfeab6c16 100644 (file)
@@ -9,16 +9,16 @@ import {getPlugin as getCustomhrPlugin} from "./plugins-customhr";
 import {getPlugin as getImagemanagerPlugin} from "./plugins-imagemanager";
 
 const style_formats = [
-    {title: "Header Large", format: "h2", preview: 'color: blue;'},
-    {title: "Header Medium", format: "h3"},
-    {title: "Header Small", format: "h4"},
-    {title: "Header Tiny", format: "h5"},
+    {title: "Large Header", format: "h2", preview: 'color: blue;'},
+    {title: "Medium Header", format: "h3"},
+    {title: "Small Header", format: "h4"},
+    {title: "Tiny Header", format: "h5"},
     {title: "Paragraph", format: "p", exact: true, classes: ''},
     {title: "Blockquote", format: "blockquote"},
     {title: "Inline Code", inline: "code"},
     {
         title: "Callouts", items: [
-            {title: "Info", format: 'calloutinfo'},
+            {title: "Information", format: 'calloutinfo'},
             {title: "Success", format: 'calloutsuccess'},
             {title: "Warning", format: 'calloutwarning'},
             {title: "Danger", format: 'calloutdanger'}
@@ -174,6 +174,10 @@ function getSetupCallback(options) {
  */
 export function build(options) {
 
+    // Set language
+    window.tinymce.addI18n(options.language, options.translationMap);
+
+    // Return config object
     return {
         width: '100%',
         height: '100%',
@@ -186,6 +190,7 @@ export function build(options) {
         body_class: 'page-content',
         browser_spellcheck: true,
         relative_urls: false,
+        language: options.language,
         directionality: options.textDirection,
         remove_script_host: false,
         document_base_url: window.baseUrl('/'),
@@ -224,9 +229,11 @@ export function build(options) {
 /**
  * @typedef {Object} WysiwygConfigOptions
  * @property {Element} containerElement
+ * @property {string} language
  * @property {boolean} darkMode
  * @property {string} textDirection
  * @property {string} drawioUrl
  * @property {int} pageId
  * @property {Object} translations
+ * @property {Object} translationMap
  */
\ No newline at end of file
index 97bfebf9a7aa96d936cff8cb9a02a3631a9bdee8..92781f02462afdda1e480e3effa1a17ee49e7c1c 100644 (file)
@@ -69,7 +69,7 @@ function register(editor, url) {
     editor.ui.registry.addIcon('codeblock', '<svg width="24" height="24"><path d="M4 3h16c.6 0 1 .4 1 1v16c0 .6-.4 1-1 1H4a1 1 0 0 1-1-1V4c0-.6.4-1 1-1Zm1 2v14h14V5Z"/><path d="M11.103 15.423c.277.277.277.738 0 .922a.692.692 0 0 1-1.106 0l-4.057-3.78a.738.738 0 0 1 0-1.107l4.057-3.872c.276-.277.83-.277 1.106 0a.724.724 0 0 1 0 1.014L7.6 12.012ZM12.897 8.577c-.245-.312-.2-.675.08-.955.28-.281.727-.27 1.027.033l4.057 3.78a.738.738 0 0 1 0 1.107l-4.057 3.872c-.277.277-.83.277-1.107 0a.724.724 0 0 1 0-1.014l3.504-3.412z"/></svg>')
 
     editor.ui.registry.addButton('codeeditor', {
-        title: 'Insert code block',
+        tooltip: 'Insert code block',
         icon: 'codeblock',
         onAction() {
             editor.execCommand('codeeditor');
index b6b768c0a97209ffa503264b7b622578c5d188ed..6b0167a7045e56fc124a54f450b47a7c68d120ee 100644 (file)
@@ -102,7 +102,7 @@ export function getPlugin(providedOptions) {
         editor.ui.registry.addIcon('diagram', `<svg width="24" height="24" fill="${options.darkMode ? '#BBB' : '#000000'}" xmlns="http://www.w3.org/2000/svg"><path d="M20.716 7.639V2.845h-4.794v1.598h-7.99V2.845H3.138v4.794h1.598v7.99H3.138v4.794h4.794v-1.598h7.99v1.598h4.794v-4.794h-1.598v-7.99zM4.736 4.443h1.598V6.04H4.736zm1.598 14.382H4.736v-1.598h1.598zm9.588-1.598h-7.99v-1.598H6.334v-7.99h1.598V6.04h7.99v1.598h1.598v7.99h-1.598zm3.196 1.598H17.52v-1.598h1.598zM17.52 6.04V4.443h1.598V6.04zm-4.21 7.19h-2.79l-.582 1.599H8.643l2.717-7.191h1.119l2.724 7.19h-1.302zm-2.43-1.006h2.086l-1.039-3.06z"/></svg>`)
 
         editor.ui.registry.addSplitButton('drawio', {
-            tooltip: 'Drawing',
+            tooltip: 'Insert/edit drawing',
             icon: 'diagram',
             onAction() {
                 editor.execCommand('drawio');
@@ -111,7 +111,7 @@ export function getPlugin(providedOptions) {
                 callback([
                     {
                         type: 'choiceitem',
-                        text: 'Drawing Manager',
+                        text: 'Drawing manager',
                         value: 'drawing-manager',
                     }
                 ]);
index 0744f113f43461c7f519d19ab67f6c5b5f60dee9..d484284cad24afb14b926ad3e7e9aa2e1e4e3a9b 100644 (file)
@@ -12,16 +12,7 @@ function register(editor, url) {
 
     editor.ui.registry.addButton('hr', {
         icon: 'horizontal-rule',
-        tooltip: 'Horizontal line',
-        onAction() {
-            editor.execCommand('InsertHorizontalRule');
-        }
-    });
-
-    editor.ui.registry.addMenuItem('hr', {
-        icon: 'horizontal-rule',
-        text: 'Horizontal line',
-        context: 'insert',
+        tooltip: 'Insert horizontal line',
         onAction() {
             editor.execCommand('InsertHorizontalRule');
         }
index d3b03e38c9fd9a02a9311fedb3fe48c4cbb33204..225f271fdb9c2c7aef16d56e0aaf578685e222f8 100644 (file)
@@ -6,9 +6,9 @@ function register(editor, url) {
 
     // Custom Image picker button
     editor.ui.registry.addButton('imagemanager-insert', {
-        title: 'Insert an image',
+        title: 'Insert image',
         icon: 'image',
-        tooltip: 'Insert an image',
+        tooltip: 'Insert image',
         onAction() {
             window.ImageManager.show(function (image) {
                 const imageUrl = image.thumbs.display || image.url;
diff --git a/resources/lang/en/editor.php b/resources/lang/en/editor.php
new file mode 100644 (file)
index 0000000..83e8f43
--- /dev/null
@@ -0,0 +1,133 @@
+<?php
+/**
+ * Page Editor Lines
+ * Contains text strings used within the user interface of the
+ * WYSIWYG page editor. Some Markdown editor strings may still
+ * exist in the 'entities' file instead since this was added later.
+ */
+return [
+    // General editor terms
+    'general' => 'General',
+    'advanced' => 'Advanced',
+    'none' => 'None',
+    'cancel' => 'Cancel',
+    'save' => 'Save',
+    'close' => 'Close',
+    'undo' => 'Undo',
+    'redo' => 'Redo',
+    'left' => 'Left',
+    'center' => 'Center',
+    'right' => 'Right',
+    'top' => 'Top',
+    'middle' => 'Middle',
+    'bottom' => 'Bottom',
+    'width' => 'Width',
+    'height' => 'Height',
+
+    // Toolbar
+    'formats' => 'Formats',
+    'header_large' => 'Large Header',
+    'header_medium' => 'Medium Header',
+    'header_small' => 'Small Header',
+    'header_tiny' => 'Tiny Header',
+    'paragraph' => 'Paragraph',
+    'blockquote' => 'Blockquote',
+    'inline_code' => 'Inline Code',
+    'callouts' => 'Callouts',
+    'callout_information' => 'Information',
+    'callout_success' => 'Success',
+    'callout_warning' => 'Warning',
+    'callout_danger' => 'Danger',
+    'bold' => 'Bold',
+    'italic' => 'Italic',
+    'underline' => 'Underline',
+    'strikethrough' => 'Strikethrough',
+    'superscript' => 'Superscript',
+    'subscript' => 'Subscript',
+    'text_color' => 'Text color',
+    'custom_color' => 'Custom color',
+    'remove_color' => 'Remove color',
+    'background_color' => 'Background color',
+    'align_left' => 'Align left',
+    'align_center' => 'Align center',
+    'align_right' => 'Align right',
+    'align_justify' => 'Align justify',
+    'list_bullet' => 'Bullet list',
+    'list_numbered' => 'Numbered list',
+    'indent_increase' => 'Increase indent',
+    'indent_decrease' => 'Decrease indent',
+    'table' => 'Table',
+    'insert_image' => 'Insert image',
+    'insert_image_title' => 'Insert/Edit Image',
+    'insert_link' => 'Insert/edit link',
+    'insert_link_title' => 'Insert/Edit Link',
+    'insert_horizontal_line' => 'Insert horizontal line',
+    'insert_code_block' => 'Insert code block',
+    'insert_drawing' => 'Insert/edit drawing',
+    'drawing_manager' => 'Drawing manager',
+    'insert_media' => 'Insert/edit media',
+    'insert_media_title' => 'Insert/Edit Media',
+    'clear_formatting' => 'Clear formatting',
+    'source_code' => 'Source code',
+    'source_code_title' => 'Source Code',
+    'fullscreen' => 'Fullscreen',
+    'image_options' => 'Image options',
+
+    // Tables
+    'table_properties' => 'Table properties',
+    'table_properties_title' => 'Table Properties',
+    'delete_table' => 'Delete table',
+    'insert_row_before' => 'Insert row before',
+    'insert_row_after' => 'Insert row after',
+    'delete_row' => 'Delete row',
+    'insert_column_before' => 'Insert column before',
+    'insert_column_after' => 'Insert column after',
+    'delete_column' => 'Delete column',
+    'table_cell' => 'Cell',
+    'table_row' => 'Row',
+    'table_column' => 'Column',
+    'cell_properties' => 'Cell properties',
+    'cell_properties_title' => 'Cell Properties',
+    'cell_type' => 'Cell type',
+    'cell_type_cell' => 'Cell',
+    'cell_type_header' => 'Header cell',
+    'table_row_group' => 'Row Group',
+    'table_column_group' => 'Column Group',
+    'horizontal_align' => 'Horizontal align',
+    'vertical_align' => 'Vertical align',
+    'border_width' => 'Border width',
+    'border_style' => 'Border style',
+    'border_color' => 'Border color',
+    'row_properties' => 'Row properties',
+    'row_properties_title' => 'Row Properties',
+    'cut_row' => 'Cut row',
+    'copy_row' => 'Copy row',
+    'paste_row_before' => 'Paste row before',
+    'paste_row_after' => 'Paste row after',
+    'row_type' => 'Row type',
+    'row_type_header' => 'Header',
+    'row_type_body' => 'Body',
+    'row_type_footer' => 'Footer',
+    'alignment' => 'Alignment',
+    'cut_column' => 'Cut column',
+    'copy_column' => 'Copy column',
+    'paste_column_before' => 'Paste column before',
+    'paste_column_after' => 'Paste column after',
+    'cell_padding' => 'Cell padding',
+    'cell_spacing' => 'Cell spacing',
+    'caption' => 'Caption',
+    'show_caption' => 'Show caption',
+    'constrain' => 'Constrain proportions',
+
+    // Images, links & embed
+    'source' => 'Source',
+    'alt_desc' => 'Alternative description',
+    'embed' => 'Embed',
+    'paste_embed' => 'Paste your embed code below:',
+    'url' => 'URL',
+    'text_to_display' => 'Text to display',
+    'title' => 'Title',
+    'open_link' => 'Open link in...',
+    'open_link_current' => 'Current window',
+    'open_link_new' => 'New window',
+];
diff --git a/resources/views/pages/parts/editor-translations.blade.php b/resources/views/pages/parts/editor-translations.blade.php
new file mode 100644 (file)
index 0000000..7b0ea7d
--- /dev/null
@@ -0,0 +1,11 @@
+@php
+    $en = trans('editor', [], 'en');
+    $lang = trans('editor');
+    $mergedText = [];
+    foreach ($en as $key => $value) {
+      $mergedText[$value] = $lang[$key] ?? $value;
+    }
+@endphp
+<script nonce="{{ $cspNonce }}">
+    window.editor_translations = @json($mergedText);
+</script>
\ No newline at end of file
index 02948fa2ecd18ed01d2d60754964d7e0207184a3..29a4b6532b596f32e3e44606d934bd4ec49e377a 100644 (file)
@@ -1,4 +1,5 @@
 <div component="wysiwyg-editor"
+     option:wysiwyg-editor:language="{{ config('app.lang') }}"
      option:wysiwyg-editor:page-id="{{ $model->id ?? 0 }}"
      option:wysiwyg-editor:text-direction="{{ config('app.rtl') ? 'rtl' : 'ltr' }}"
      option:wysiwyg-editor:image-upload-error-text="{{ trans('errors.image_upload_error') }}"
@@ -11,4 +12,6 @@
 
 @if($errors->has('html'))
     <div class="text-neg text-small">{{ $errors->first('html') }}</div>
-@endif
\ No newline at end of file
+@endif
+
+@include('pages.parts.editor-translations')
\ No newline at end of file