Building a simple custom plugin to TinyMce in Episerver.Cms.TinyMce package 2
Having to upgrade TinyMCE in Episerver to latest packages and you have elder plugins? Or want to build some custom plugin in wysiwyg? Here is a very simple example of how.
Published 1st September 2018
Episerver 11
Episerver.Cms.TinyMce > 2.0
TinyMce > 4.0
In this blog post I’ll give you an example how to implement a custom button plugin in tinyMCE.
Check out my other tinyMCE plugin tips here
- Example: “A background plate”, a custom button that wraps content into a div with class.
So… 2 steps
- Code a tinymce.PluginManager js class
- Register the script and plugin
tinymce.PluginManager.add
The main parts in a plugin is explained with this image:
- Use tinymce.PluginManager.add to register
- addCommand is used for you custom logic
- addButton to add your button to toolbar
- monitorNodeChange is non mandatory, where you can put logic for enabling/disabling your button
Adding your plugin to in a non Episerver site
Add scripts to site:
<script src=”/tinymce/js/tinymce.min.js”></script><script src=”/ClientResources/Scripts/tinymce/plugins/customplateplugin/editor_plugin_v4.js “></script>
Then init tiny:
tinymce.init({ selector: ‘textarea’,
plugins: ‘customplateplugin’,
toolbar: ‘customplateplugin’
});
How to add your external plugin to Episerver XhtmlString property
using EPiServer.Cms.TinyMce.Core; using EPiServer.Framework; using EPiServer.Framework.Initialization; using EPiServer.ServiceLocation; namespace Gosso.Mvc.Business.Initialization { [ModuleDependency(typeof(TinyMceInitialization))] public class CustomizedTinyMceInitialization : IConfigurableModule { public void Initialize(InitializationEngine context) { } public void Uninitialize(InitializationEngine context) { } public void ConfigureContainer(ServiceConfigurationContext context) { context.Services.Configure<TinyMceConfiguration>(config => { config.Default() .AddPlugin("code")// i do want see code .Toolbar(DefaultValues.Toolbar + " | code customplateplugin") .AddExternalPlugin("customplateplugin", "/ClientResources/Scripts/tinymce/plugins/customplateplugin/editor_plugin_v4.js") }); } } }
CSS
You need this CSS to add on site and tinyMCE for this plugin to work:
.plate {
padding: 25px;
background-color: lightgray;
}
The complete js code:
https://gist.github.com/LucGosso/b5c723b832435b8ae396487ef5befdc3#file-editor_plugin_plate-js
"use strict"; var tinymce = tinymce || {}; //Register the plugin tinymce.PluginManager.add('customplateplugin', function (ed, url) {// ed as editor var cssClass = "plate";// your classname //your custom logic when button clicked ed.addCommand('customplatecmd', function () { if (ed.selection.getNode().parentElement.className === cssClass) { var bm = ed.selection.getBookmark(); ed.selection.getNode().parentElement.outerHTML = ed.selection.getNode().parentElement.innerHTML; ed.selection.moveToBookmark(bm); } else if (ed.selection.getNode().parentElement.parentElement != undefined && ed.selection.getNode().parentElement.parentElement.className === cssClass) { var bm = ed.selection.getBookmark(); ed.selection.getNode().parentElement.parentElement.outerHTML = ed.selection.getNode().parentElement.parentElement.innerHTML; ed.selection.moveToBookmark(bm); } else { if (ed.selection.getSelectedBlocks().length > 1) { ed.selection.setContent('<div class="' + cssClass+'">' + ed.selection.getContent() + '</div>'); ed.focus(); } else { if (ed.selection.getNode().nodeName === "P") { // Stores a bookmark of the current selection var bm = ed.selection.getBookmark(); ed.selection.select(ed.selection.getNode(), true); ed.selection.setContent('<div class="' + cssClass+'">' + ed.selection.getNode().outerHTML + '</div>'); // Restore the selection bookmark ed.selection.moveToBookmark(bm); } else if (ed.selection.getNode().parentNode.nodeName === "P") { ed.selection.select(ed.selection.getNode().parentNode, true); ed.selection.setContent('<div class="' + cssClass+'">' + ed.selection.getNode().outerHTML + '</div>'); } ed.focus(); } } }); // Register custom button ed.addButton('customplateplugin', { title: 'Plate', cmd: 'customplatecmd', image: url + '/img/plate.png', onclick: function () { ed.focus(); //ed.selection.setContent('Hello world!'); window.tinyMCE.activeEditor.execCommand('customplatecmd'); } , onpostrender: monitorNodeChange //remove this if you would be able to mark several blocks }); // Add a node change handler, selects the button in the UI when a P tag is selected function monitorNodeChange() { var btn = this; ed.on('NodeChange', function (e) { btn.disabled(!e.element || !e.element.nodeName || (e.element.nodeName.toLowerCase() !== "p" && e.element.parentNode.nodeName.toLowerCase() !== "p"));// }); } return { getMetadata: function () { return { name: 'Gray plate plugin', url: 'https://devblog.gosso.se/?p=796' }; } }; });
SEO Terms
- Add Plugins to TinyMCE
- TinyMceInitialization example
Resources
- https://world.episerver.com/documentation/developer-guides/CMS/add-ons/customizing-the-tinymce-editor-v2/
- https://world.episerver.com/blogs/Ben-McKernan/Dates/2018/3/an-updated-tinymce-package-has-been-released/
- https://www.tinymce.com/docs/advanced/creating-custom-dialogs/
- https://www.tiny.cloud/docs/api/tinymce/tinymce.windowmanager/#open
- https://www.tiny.cloud/docs/advanced/creating-a-plugin/
About the author
Luc Gosso
– Independent Senior Web Developer
working with Azure and Episerver
Twitter: @LucGosso
LinkedIn: linkedin.com/in/luc-gosso/
Github: github.com/lucgosso