網上大部分涉及tinymce插件開發的文章以4.x和5.x版本為主,而目前最新的6.x版很多老插件都無法正常加載或運作了。
基本流程:
本開發流程以一個包含checkbox元件的彈窗為例:
- 建立插件檔案夾,例如
,檔案夾中建立三個檔案:myplugin
用于引導;index.js
開發主檔案;plugin.js
已打封包件,選擇plugin.min.js
時自動調用。tinymce.min.js
- 在
檔案中定義插件,使用 TinyMCE 的插件系統注冊插件。plugin.js
- 在插件中定義彈窗,使用 TinyMCE 的 UI 元件系統建立彈窗。
- 在彈窗中添加
和說明,使用 TinyMCE 的 UI 元件系統添加checkbox
和說明。checkbox
- 在确定按鈕事件處理函數中,根據
的值修改編輯器内的文本。checkbox
- 在 TinyMCE 配置中啟用插件,使用 TinyMCE 的配置系統啟用插件。
以下代碼為Element-UI頁面中調用自定義元件方法,本文的插件代碼案例都以此為目标地。
// view/tinymcetest.vue
<template>
<div>
<Editor
:init="init"
/>
</div>
</template>
<script setup>
import Editor from "@tinymce/tinymce-vue"
import 'tinymce/tinymce'
...
import 'tinymce/plugins/myplugin'
const init = {
plugins: 'myplugin',
toolbar: 'myplugin',
mybold:true, //自定義參數
}
</script>
4.x和5.x版本通用代碼:
如果你對這兩個版本很熟悉了,那麼可以直接忽略本小節。
tinymce.PluginManager.add('myplugin', function(editor) {
// Add a button that opens a window
// editor.addButton('myplugin', { // 4.x版
editor.ui.registry.addButton('myplugin', { // 5.x版
text: 'My Button',
onAction: function() {
// Open window
editor.windowManager.open({
title: 'My Plugin Window',
body: [
{
type: 'checkbox',
name: 'bold',
text: 'Bold',
checked: false
},{
type: 'checkbox',
name: 'italic',
text: 'Italic',
checked: true
}
],
onSubmit: function(e) {
// Get the values from the checkboxes
var bold = e.data.bold;
var italic = e.data.italic;
// Modify the text in the editor
var text = editor.selection.getContent({format: 'text'});
var style = '';
if (bold) {
style += 'font-weight: bold;';
}
if (italic) {
style += 'font-style: italic;';
}
editor.insertContent('<span style="' + style + '">' + text + '</span>');
}
});
}
});
});
這段代碼實作了以下功能:
- 添加一個名為 “My Button” 的按鈕。
- 點選按鈕時打開一個名為 “My Plugin Window” 的彈窗。
- 彈窗中包含兩個 checkbox,一個是 “Bold”,一個是 “Italic”。
- 點選确定按鈕後,擷取 checkbox 的值,并将選中的文本改為粗體或斜體(或兩者都是)。
如果使用了 TinyMCE Vue 元件,則插件開發方式與上面給出的代碼略有不同。具體而言,您需要使用 Vue 插件,而不是 TinyMCE 插件。這是因為 TinyMCE Vue 元件是通過 Vue 元件包裝 TinyMCE 編輯器,并允許您使用 Vue 元件的形式與 TinyMCE 編輯器進行互動。
以下示範在 TinyMCE Vue 中實作該功能插件:
import Vue from 'vue'
const MyPlugin = {
install(editor, url) {
// editor.addButton('myplugin', { // 4.x版
editor.ui.registry.addButton('myplugin', { // 5.x版
text: 'My Button',
onAction: function() {
// Open window
editor.windowManager.open({
title: 'My Plugin Window',
body: [
{
type: 'checkbox',
name: 'bold',
text: 'Bold',
checked: false
},{
type: 'checkbox',
name: 'italic',
text: 'Italic',
checked: true
}
],
onSubmit: function(e) {
// Get the values from the checkboxes
var bold = e.data.bold;
var italic = e.data.italic;
// Modify the text in the editor
var text = editor.selection.getContent({format: 'text'});
var style = '';
if (bold) {
style += 'font-weight: bold;';
}
if (italic) {
style += 'font-style: italic;';
}
editor.insertContent('<span style="' + style + '">' + text + '</span>');
}
});
}
});
}
}
Vue.use(MyPlugin)
6.x和7.x版本案例分析與總結:
雖然整體思路還是差不多,但6.x以上版本中有很多規範、函數都變了,可能删除,可能修改,可能新增:
- 官方風格:在
的立即執行函數plugin.js
中寫一個具備注冊按鈕或菜單等功能的函數并且運作該函數;(function(){...})
-
使用tinymce中的功能需要先加載對應子產品
a)
tinymce.util.Tools.resolve('tinymce.PluginManager')
方法加載插件子產品;
b)
方式操作 ;tinymce.PluginManager
- 彈窗配置中必須配置按鈕參數
;buttons
buttons: [{
type: 'cancel',
name: 'cancel',
text: 'Cancel'
},{
type: 'submit',
name: 'save',
text: 'Save',
primary: true
}]
- 插件名如果是
,那麼myplugin
時候的按鈕名也是addButton()
才能顯示;myPlugin
global.add('myplugin', editor => {
editor.ui.registry.addButton('myplugin', {});
});
- 在不同版本下,各種元件的屬性可能有所差異,比如原來的
,現在可能是text
;label
- 擷取元件值的方法為
,老版本使用.getData()
;.data
- 元件初始值(非預設值)需要在
中給對應元件initialData
指派,而老版本則可能是使用諸如name
;checked:true
// checked為true,在打開面闆的時候,對應的checkbox将會被選中
body: [{
type: "container",
items: [{
type: 'checkbox',
name: 'bold',
text: 'Bold',
checked:true
}]
// initialData中設定了初始值,那麼在打開面闆的時候,對應的checkbox将會被選中
body:{
type: 'panel',
items: [{
type: 'checkbox',
name: 'bold',
label: 'Bold'
}
]},
initialData:{
bold: true,
}
-
或.options.get()
函數從目前editor編輯器中獲得參數,一般用于插件預設值或函數,在調用tinymce時的.getParam()
參數中配置;init
.getParam(name: String, defaultVal: String, type: String): String
按名稱傳回配置參數,其中包含了預設值。
但在 TinyMCE 6.0 中已棄用,雖然還能實作,但在 TinyMCE 7.0 中标記為删除,改用
,具體實作看案例比較。.options.get
// Returns a specific config value from the currently active editor
const someval = tinymce.activeEditor.getParam('myvalue');
// Returns a specific config value from a specific editor instance by id
const someval2 = tinymce.get('my_editor').getParam('myvalue');
- 原來使用
的方法結合了注冊預設值和擷取目前值,但最新版本中已将這兩個功能分開了。getParam()
// 4.x 5.x 6.x版方法
editor.getParam('mybold',true); //如果mybold參數不存在,則為true
// 6.x 7.x版方法
const registerOption = editor.options.register; // 注冊預設值
registerOption('mybold', {
processor: 'boolean',
default: true
});
editor.options.get('mybold') // 擷取目前值
按照官方風格寫插件
// node_modules/tinymce/plugins/myplugin/plugin.js
(function () {
'use strict';
//Load plugin util
var global = tinymce.util.Tools.resolve('tinymce.PluginManager');
const MyPlugin = () => {
global.add('myplugin', editor => {
// get option and set default value 另一種擷取init參數的方法,本案例使用6.0官方風格擷取
/*const setting = {
bold: editor.getParam('mybold',false),
italic: editor.getParam('myitalic',false)
};*/
// reg option 注冊預設值
editor.options.register('mybold', {
processor: 'boolean',
default: true
});
editor.options.register('myitalic', {
processor: 'boolean',
default: true
});
// Get option 擷取目前值
const setting = {
bold: editor.options.get('mybold'),
italic: editor.options.get('myitalic')
};
// Add a button that opens a window
editor.ui.registry.addButton('myplugin', {
text: 'My Button',
onAction: function() {
// Open window
editor.windowManager.open({
title: 'My Plugin Window',
body:{
type: 'panel',
items: [{
type: 'checkbox',
name: 'bold',
label: 'Bold'
},{
type: 'checkbox',
name: 'italic',
label: 'Italic'
}
]},
buttons: [{
type: 'cancel',
name: 'cancel',
text: 'Cancel'
},{
type: 'submit',
name: 'save',
text: 'Save',
primary: true
}],
//Like [input:name=bold].checked=true;[input:name=italic].checked=false;
initialData:{
bold: setting.bold,
italic: setting.italic
},
onSubmit: e => {
// Get the values from the checkboxes
var bold = e.getData().bold;
var italic = e.getData().italic;
// Modify the text in the editor
var text = editor.selection.getContent({format: 'text'});
var style = '';
if (bold) {
style += 'font-weight: bold;';
}
if (italic) {
style += 'font-style: italic;';
}
editor.insertContent('<span style="' + style + '">' + text + '</span>');
// Close window
e.close();
}
});
}
});
});
};
// Run
MyPlugin();
})();
按照老版本代碼修改插件
在老版本基礎上修改了新版裡對應的部分,下面的代碼也可直接放于
vue
頁面中,無需用
import
引用。
其中
getParam()
函數目前也可用在官方風格的插件中,但未來可能被禁用。
// node_modules/tinymce/plugins/myplugin/plugin.js
tinymce.PluginManager.add('myplugin', function(editor, url) {
// get option and set default value
const setting = {
bold: editor.getParam('mybold',false),
italic: editor.getParam('myitalic',false)
};
// Add a button that opens a window
editor.ui.registry.addButton('myplugin', {
text: 'My Button',
onAction: function() {
// Open window
editor.windowManager.open({
title: 'My Plugin Window',
body:{
type: 'panel',
items:[
{
type: 'checkbox',
name: 'bold',
label: 'Bold'
},
{
type: 'checkbox',
name: 'italic',
label: 'Italic'
}
]},
buttons: [{
type: 'cancel',
name: 'cancel',
text: 'Cancel'
},{
type: 'submit',
name: 'save',
text: 'Save',
primary: true
}],
//Like [input:name=bold].checked=true;[input:name=italic].checked=false;
initialData:{
bold: setting.bold,
italic: setting.italic
},
onSubmit: function(e) {
// Get the values from the checkboxes
var bold = e.getData().bold;
var italic = e.getData().italic;
// Modify the text in the editor
var text = editor.selection.getContent({format: 'text'});
var style = '';
if (bold) {
style += 'font-weight: bold;';
}
if (italic) {
style += 'font-style: italic;';
}
editor.insertContent('<span style="' + style + '">' + text + '</span>');
}
});
}
});
});
進階學習
-
icon
Icons Available for TinyMCE
TinyMCE 富文本編輯器 ━━ (Version: 5.0.4)内含icon對照表
-
ui
打開連結後看左側清單所在位置為
Creating custom dialogsCreating custom UI components
-
參數注冊、設定與删除
tinymce.EditorOptions
-
彈窗布局群組件
Custom dialog body components
-
Element-UI打包後仍舊為老插件,重新整理也沒用
找到
檔案,删除該下面部分後,重新打包即可。node_modules\.vite\deps\_metadata.json
"tinymce/plugins/myplugin": {
"src": "../../tinymce/plugins/myplugin/index.js",
"file": "tinymce_plugins_myplugin.js",
"fileHash": "1234567",
"needsInterop": true
}
仿複雜化官方代碼
參考官方的插件代碼書寫,将上面寫的代碼再進一步複雜化~~看懂後,自己看官方插件也基本沒問題了
(function () {
'use strict';
//Load plugin util
var global = tinymce.util.Tools.resolve('tinymce.PluginManager');
// reg option
const register = editor => {
const registerOption = editor.options.register;
registerOption('mybold', {
processor: 'boolean',
default: true
});
registerOption('myitalic', {
processor: 'boolean',
default: true
});
};
// get option
const option = name => editor => editor.options.get(name);
const setting = {
bold: option('mybold'),
italic: option('myitalic')
};
const MyPlugin = () => {
global.add('myplugin', editor => {
// reg option
register(editor);
// Add a button that opens a window
editor.ui.registry.addButton('myplugin', {
text: 'My Button',
icon: 'bold',
onAction: function() {
// Open window
editor.windowManager.open({
title: 'My Plugin Window',
body:{
type: 'panel',
items: [{
type: 'checkbox',
name: 'bold',
label: 'Bold'
},{
type: 'checkbox',
name: 'italic',
label: 'Italic'
}
]},
buttons: [{
type: 'cancel',
name: 'cancel',
text: 'Cancel'
},{
type: 'submit',
name: 'save',
text: 'Save',
primary: true
}],
//Like [input:name=bold].checked=true;[input:name=italic].checked=false;
initialData:{
bold: setting.bold(editor),
italic: setting.italic(editor),
},
onSubmit: e => {
// Get the values from the checkboxes
var bold = e.getData().bold;
var italic = e.getData().italic;
// Modify the text in the editor
var text = editor.selection.getContent({format: 'text'});
var style = '';
if (bold) {
style += 'font-weight: bold;';
}
if (italic) {
style += 'font-style: italic;';
}
editor.insertContent('<span style="' + style + '">' + text + '</span>');
// Close window
e.close();
}
});
}
});
});
};
// Run
MyPlugin();
})();
參考(其中提供的代碼不一定适合tinymce6):
三種插件開發模式,帶你玩廢tinymce
tinymce系列(二) tinymce 插件開發
關于tinymce插件,開發的自由表單、病曆插件
富文本插件tinymce.init()最全配置參數說明
Element-UI中調用tinymce6如何實作本地化加載,如何解決提示:This domain is not registered with TinyMCE Cloud,必須要api-key麼?