tinymce Editor Library files not load when tab is inactive in Angular 5 - mat-tab

I want to use tinymce editor in Angular 5 on mat-tab. But when the tab is inactive it can't load the scripts files which will required for the tinymce editor.
Here is my HTML Code
<mat-tab-group>
<mat-tab label="Document Info">
<p> This is document information </p>
</mat-tab>
<mat-tab label="Add Note">
<div>
<h3 for="post-body">Editor</h3>
<text-editor [elementId]="'post-body' (onEditorKeyup)="onBody($event)">
</text-editor>
</div>
</mat-tab>
</mat-tab-group>

After spending some time testing I came up with a simple solution. Please feel free to make alterations and provide a better solution to the community as this solution is rather a quick tactical fix than solving the actual problem.
At the top of your component file, below your imports, add the following declaration:
declare var tinymce: any;
In your class, create new properties.
tabIndex: number;
content: string = ' ';
Add the following function to your class. The specified tabIndex would be the tab the editor resides in. The tab indexing starts with 0 (being the first tab).
tabChanged() {
if ( this.tabIndex == 1 ) {
tinymce.execCommand("mceToggleEditor", false, 'content');
} else {
tinymce.remove();
}
}
Change your mat-tab-group element to the following.
<mat-tab-group [(selectedIndex)]="tabIndex" (selectedTabChange)="tabChanged()">
If your editor renders with a textarea inside, make sure you have some default content to load e.g. for records that does not have a value yet.
<editor placeholder="Content" [(ngModel)]="content" name="content" id="content" #content [init]="{skin_url: '/assets/skins/lightgray', plugins: 'link,image', height: '450'}"></editor>
That's it.

Use Multiple instances of tinymce
import 'tinymce/tinymce.min.js';
import 'tinymce/themes/modern/theme';
import '../assets/emoticons/plugin.js';
import 'tinymce/plugins/paste/plugin.js';
import 'tinymce/plugins/link/plugin.js';
import 'tinymce/plugins/autoresize/plugin.js';
import 'tinymce/plugins/image/plugin.js';
import 'tinymce/plugins/imagetools/plugin.js';
import 'tinymce/plugins/searchreplace/plugin.js';
import 'tinymce/plugins/autolink/plugin.js';
import 'tinymce/plugins/fullscreen/plugin.js';
import 'tinymce/plugins/media/plugin.js';
import 'tinymce/plugins/table/plugin.js';
import 'tinymce/plugins/hr/plugin.js';
import 'tinymce/plugins/insertdatetime/plugin.js';
import 'tinymce/plugins/advlist/plugin.js';
import 'tinymce/plugins/lists/plugin.js';
import 'tinymce/plugins/textcolor/plugin.js';
import 'tinymce/plugins/contextmenu/plugin.js';
import 'tinymce/plugins/colorpicker/plugin.js';
import 'tinymce/plugins/help/plugin.js';
declare var tinymce: any;
public notes = {
selector: '#notes',
height: 500,
width: '40%',
skin_url: 'skins/lightgray',
plugins_url: '/test/',
document_base_url: 'assets',
plugins: [
'emoticons',
'paste',
'link',
'autoresize',
'image',
'imagetools',
'searchreplace',
'autolink',
'fullscreen',
'media',
'table',
'hr',
'insertdatetime',
'advlist',
'lists',
'textcolor',
'contextmenu',
'colorpicker',
'help'
],
toolbar1: 'newdocument fullscreen media | \
emoticons | undo redo cut copy paste pastetext | \
formatselect fontsizeselect subscript superscript | \
bold italic strikethrough forecolor backcolor | link | \
alignleft aligncenter alignright alignjustify | \
numlist bullist outdent indent | removeformat | image | help',
image_advtab: true,
imagetools_toolbar: 'rotateleft rotateright | flipv fliph | editimage imageoptions',
paste_data_images: true
};
public details = {
selector: '#opportunity',
height: 500,
width: '40%',
skin_url: 'skins/lightgray',
plugins_url: '/test/',
document_base_url: 'assets',
plugins: [
'emoticons',
'paste',
'link',
'autoresize',
'image',
'imagetools',
'searchreplace',
'autolink',
'fullscreen',
'media',
'table',
'hr',
'insertdatetime',
'advlist',
'lists',
'textcolor',
'contextmenu',
'colorpicker',
'help'
],
// tslint:disable-next-line:max-line-length
// toolbar2: 'formatselect | bold italic strikethrough forecolor backcolor | link | alignleft aligncenter alignright alignjustify | numlist bullist outdent indent | removeformat',
toolbar1: 'newdocument fullscreen media | emoticons | undo redo cut copy paste pastetext | \
formatselect fontsizeselect subscript superscript | \
bold italic strikethrough forecolor backcolor | link | \
alignleft aligncenter alignright alignjustify | \
numlist bullist outdent indent | removeformat | image | help',
image_advtab: true,
imagetools_toolbar: 'rotateleft rotateright | flipv fliph | editimage imageoptions',
paste_data_images: true
};
public ngAfterViewInit(): void {
tinymce.init(this.details); //to show on first tab initially
}
In your mat-tab-group use a tab change function passing it the event
<mat-tab-group #tabGroup (selectedTabChange)="tabSwitch($event)">
**Then the function processing the event gets rid of previous instances before initializing another*
tabSwitch(tabEvent: MatTabChangeEvent) {
switch (tabEvent.index) {
case (0):
tinymce.remove();
tinymce.init(this.details);
break;
case (2):
tinymce.remove();
tinymce.init(this.notes);
break;
default:
tinymce.remove();
break;
}
}

Related

Vite: ?inline not working as expected when loading css for TinyMCE

I am implementing self hosted TinyMCE in my application.
I am referring this link for the implementation. Here is my code
/* TinyMCE scripts loading here. All good! */
import contentUiCss from 'tinymce/skins/ui/oxide/content.css?inline';
import contentCss from 'tinymce/skins/content/default/content.css?inline';
tinymce.init({
selector: '#my_text_area',
inline: true,
menubar: false,
toolbar: 'undo redo | bold italic underline | alignleft aligncenter alignright',
placeholder: 'Write your text here',
skin: false, // skin is loaded manually above as an import
content_css: false, // loaded manually directly below
content_style: [contentCss, contentUiCss].join('\n'),
});
The contents from content.css and contentUiCss are also getting injected in my <head> section which is causing the css conflicts.
As per the fix of Vite, it should not happen this way. Where am I getting wrong?
Vite version: 3.1.0
PS: Tried with ?raw as well but no luck!
Found the solution.
This is not because of Vite but because of TinyMCE. As per the documentation of TinyMCE
In inline mode, it (CSS provided) is injected into the head of the page TinyMCE is rendered in.
Fix for this:
You do not need tinymce/skins/content/default/content.css. The code works perfectly fine even without it (At least as of now)
For the other one, we have a file in the oxide folder for inline mode: tinymce/skins/ui/oxide/content.inline.css
So, the updated working code is:
import contentUiCss from 'tinymce/skins/ui/oxide/content.inline.css?inline';
tinymce.init({
selector: '#my_text_area',
inline: true,
menubar: false,
toolbar: 'undo redo | bold italic underline | alignleft aligncenter alignright',
placeholder: 'Write your text here',
skin: false, // skin is loaded manually above as an import
content_css: false, // loaded manually directly below
content_style: contentUiCss,
});
And it's all good to go!
Hope it helps someone! :)

How to add custom plugin in CKEditor 5 on Laravel Vue 2

How to add a custom plugin, more specifically the Inline widget plugin as mentioned in the example of the documentation of CKEditor in vue CKEditor ?
I have tried to follow the CKEditor setup process using CKEditor from source.
Since Laravel Vue doesn't have vue.config.js i have copied the same code on webpack.mix.js. Initially it failed to complied with an error
Module not found: Error: Can't resolve './#ckeditor/ckeditor5-ui/theme/mixins/_rwd.css' in '
But after removing some of the plugins such as `LinkPlugin, it complies but it run into another error
app.js?id=00c39e33120645d3026e:82180 TypeError: Cannot read properties of null (reading 'getAttribute')
at IconView._updateXMLContent (app.js?id=00c39e33120645d3026e:63098)
at IconView.render (app.js?id=00c39e33120645d3026e:63074)
at IconView.<anonymous> (app.js?id=00c39e33120645d3026e:80777)
at IconView.fire (app.js?id=00c39e33120645d3026e:78186)
at IconView.<computed> [as render] (app.js?id=00c39e33120645d3026e:80781)
at ViewCollection._renderViewIntoCollectionParent (app.js?id=00c39e33120645d3026e:72022)
at ViewCollection.<anonymous> (app.js?id=00c39e33120645d3026e:71883)
at ViewCollection.fire (app.js?id=00c39e33120645d3026e:78186)
at ViewCollection.addMany (app.js?id=00c39e33120645d3026e:74031)
at ViewCollection.add (app.js?id=00c39e33120645d3026e:73996)
Same issue as mentioned here
https://github.com/ckeditor/ckeditor5-vue/issues/24#issuecomment-947333698
But this solution didn't work for me.
Here is my complete webpack.mix.js file
let mix = require('laravel-mix');
/*
|--------------------------------------------------------------------------
| Mix Asset Management
|--------------------------------------------------------------------------
|
| Mix provides a clean, fluent API for defining some Webpack build steps
| for your Laravel application. By default, we are compiling the Sass
| file for the application as well as bundling up all the JS files.
|
*/
mix.js('resources/assets/js/app.js', 'public/js')
.sass('resources/assets/sass/app.scss', 'public/css')
.version();
const path = require('path');
const CKEditorWebpackPlugin = require('#ckeditor/ckeditor5-dev-webpack-plugin');
const {styles} = require('#ckeditor/ckeditor5-dev-utils');
module.exports = {
// The source of CKEditor is encapsulated in ES6 modules. By default, the code
// from the node_modules directory is not transpiled, so you must explicitly tell
// the CLI tools to transpile JavaScript files in all ckeditor5-* modules.
transpileDependencies: [
/ckeditor5-[^/\\]+[/\\]src[/\\].+\.js$/,
],
configureWebpack: {
plugins: [
// CKEditor needs its own plugin to be built using webpack.
new CKEditorWebpackPlugin({
// See https://ckeditor.com/docs/ckeditor5/latest/features/ui-language.html
language: 'en',
// Append translations to the file matching the `app` name.
translationsOutputFile: /app/
})
]
},
// Vue CLI would normally use its own loader to load .svg and .css files, however:
// 1. The icons used by CKEditor must be loaded using raw-loader,
// 2. The CSS used by CKEditor must be transpiled using PostCSS to load properly.
chainWebpack: config => {
// (1.) To handle editor icons, get the default rule for *.svg files first:
const svgRule = config.module.rule('svg');
// More rule
const filesRuleIndex = config.module.rules.findIndex(item => {
return item.test.test('.svg')
})
if (filesRuleIndex !== -1) {
config.module.rules[filesRuleIndex].test = /\.(png|jpe?g|gif|webp)$/
const svgRule = {...config.module.rules[filesRuleIndex]}
svgRule.test = /\.svg/
svgRule.exclude = svgRule.exclude || []
svgRule.exclude.push(path.join(__dirname, 'node_modules', '#ckeditor'))
config.module.rules.push(svgRule)
}
config.module.rules.push({
test: /ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/,
use: ["raw-loader"]
})
// Then you can either:
//
// * clear all loaders for existing 'svg' rule:
//
// svgRule.uses.clear();
//
// * or exclude ckeditor directory from node_modules:
svgRule.exclude.add(path.join(__dirname, 'node_modules', '#ckeditor'));
// Add an entry for *.svg files belonging to CKEditor. You can either:
//
// * modify the existing 'svg' rule:
//
// svgRule.use( 'raw-loader' ).loader( 'raw-loader' );
//
// * or add a new one:
config.module
.rule('cke-svg')
.test(/ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/)
.use('raw-loader')
.loader('raw-loader');
// (2.) Transpile the .css files imported by the editor using PostCSS.
// Make sure only the CSS belonging to ckeditor5-* packages is processed this way.
config.module
.rule('cke-css')
.test(/ckeditor5-[^/\\]+[/\\].+\.css$/)
.use('postcss-loader')
.loader('postcss-loader')
.tap(() => {
return styles.getPostCssConfig({
themeImporter: {
themePath: require.resolve('#ckeditor/ckeditor5-theme-lark'),
},
minify: true
});
});
},
};
Can anyone please tell me what is the proper way of setting this CKEditor to work with custom plugins
And my vue component script is like this
import CKEditor from '#ckeditor/ckeditor5-vue2';
import ClassicEditor from '#ckeditor/ckeditor5-editor-classic/src/classiceditor';
import EssentialsPlugin from '#ckeditor/ckeditor5-essentials/src/essentials';
import BoldPlugin from '#ckeditor/ckeditor5-basic-styles/src/bold';
import ItalicPlugin from '#ckeditor/ckeditor5-basic-styles/src/italic';
//import LinkPlugin from '#ckeditor/ckeditor5-link/src/link';
import ParagraphPlugin from '#ckeditor/ckeditor5-paragraph/src/paragraph';
//Custom Plugin same as in the documentation mentioned above,
//import Placeholder from "../../editor-plugins/Placeholder"; // Commented out
export default {
name: "AddEditDocuments",
props: {},
components:{
ckeditor: CKEditor.component
},
data() {
return {
editor: ClassicEditor,
editorData: '',
editorConfig: {
plugins: [
EssentialsPlugin,
BoldPlugin,
ItalicPlugin,
// LinkPlugin,
ParagraphPlugin
],
toolbar: {
items: [
'bold',
'italic',
'link',
'undo',
'redo'
]
}
},\
}
Packages:
Laravel : 8.76.1
Vue 2
CKEditor 5
Dont use CKEditor5 as it has some bugs in its editor just because of this i was also switch to CKEditor 4. After installing CKeditor using npm use it in the component. No need to configure it globally.
<template>
<ckeditor v-model="obj[name]" :config="editorConfig" ></ckeditor>
</template>
<script>
import CKEditor from 'ckeditor4-vue';
export default {
name: "Ckeditor",
props: {
obj: {
type: Object,
required: true,
},
name: {
type: String,
required: true,
}
},
components: {
ckeditor: CKEditor.component
},
data(){
return {
editorConfig: {
toolbar: [
[
'Bold',
'Italic',
'Link',
'BulletedList',
'NumberedList',
'Undo',
'Redo',
]
],
removePlugins: 'elementspath',
extraPlugins: 'filebrowser,uploadimage',
height: 100,
resize_enabled:false,
}
}
}
}
</script>
<style scoped>
</style>

Laravel Voyager Tinymce Plugin issue

I am trying to add a plugin to Tinymce in voyager, however I keep getting this
Failed to load plugin: template from url http://domain/admin/plugins/template/plugin.js net::ERR_ABORTED 404 (Not Found)
I've tried to place plugins folder in public or in vendor tcg public folder but nothing work. I've also tried to load plugins from external, still no luck.
Can someone please help Thank you.
function tinymce_init_callback(editor) {
console.log('Init!');
editor.remove();
editor = null;
tinymce.init({
menubar: false,
selector: 'textarea.richTextBox',
skin_url: $('meta[name="assets-path"]').attr('content')+'?path=js/skins/voyager',
min_height: 600,
resize: 'vertical',
plugins: 'link, image, code, table, textcolor, lists, template',
extended_valid_elements : 'input[id|name|value|type|class|style|required|placeholder|autocomplete|onclick]',
file_browser_callback: function(field_name, url, type, win) {
if(type =='image'){
$('#upload_file').trigger('click');
}
},
toolbar: 'styleselect bold italic underline | forecolor backcolor | alignleft aligncenter alignright | bullist numlist outdent indent | link image table | code',
convert_urls: false,
image_caption: true,
image_title: true,
// external_plugins: {
// 'link': '/tinymce/plugins/link/plugin.js',
// 'image': '/tinymce/plugins/image/plugin.js',
// 'code': '/tinymce/plugins/code/plugin.js',
// 'table': '/tinymce/plugins/table/plugin.js',
// 'textcolor': '/tinymce/plugins/textcolor/plugin.js',
// 'lists': '/tinymce/plugins/lists/plugin.js',
// 'template': '/tinymce/plugins/template/plugin.js',
// }
});
}
I try this also, my solution is:
add to your composer.json
"tinymce/tinymce": "4.9.11"
because Voyager 1.5 comes with this version of tinymce.
run composer update in your terminal to install this version in /vendor
copy the /vendor/tinymce/tinymce directory to /public/js/tinymce
this is my callback function in the custom.js as mentation from the Voyager documentation
function tinymce_init_callback(editor) {
editor.remove();
editor = null;
tinymce.init({
menubar: false,
selector: 'textarea.richTextBox',
skin_url: $('meta[name="assets-path"]').attr('content') + '?path=js/skins/voyager',
min_height: 100,
height: 500,
resize: 'vertical',
inline_styles: false,
keep_styles: false,
font_formats: 'Open Sans, sans-serif',
plugins: 'link, image, code, table, textcolor, lists',
file_browser_callback: function (field_name, url, type, win) {
if (type == 'image') {
$('#upload_file').trigger('click');
}
},
toolbar: 'styleselect bold italic underline | forecolor backcolor | alignleft aligncenter alignright | bullist numlist outdent indent | anchor link image table | print | emoticons | code',
convert_urls: false,
image_caption: true,
image_title: true,
valid_elements: 'div[*],p[*],span[*],ul[*],li[*],ol[*],hr,br,img[*],i[*],em,table[*],tr[*],td[*],th[*],sup[*],sub[*],strong[*],b,h1[*],h2[*],h3[*],h4[*],h5[*],h6[*],small[*],a[*], svg,path',
valid_children: '+li[p]',
external_plugins: {
'anchor': '/js/tinymce/plugins/anchor/plugin.min.js',
'print': '/js/tinymce/plugins/print/plugin.min.js',
'preview': '/js/tinymce/plugins/preview/plugin.min.js',
'emoticons': '/js/tinymce/plugins/emoticons/plugin.min.js',
}
});
Note the "/js" in front of the path to the external plugins.
Plugins are loaded and working.
Check /public/js/tinymce/plugins to see the available plugins who come with this version.

How to import/use ckeditor 5 from online-builder in Vue 3?

I create custom ckeditor 5 build in https://ckeditor.com/ckeditor-5/online-builder/ (based on "decoupled component" type), at the end i download zip with files. But what I am supposed to do next how to import it in main.js / package.js and finnaly to component ?
All materials I was able to find are https://ckeditor.com/docs/ckeditor5/latest/builds/guides/integration/frameworks/vuejs-v3.html , got decoupled-document preset build working, but wanted to add image resize, so created custom build and am stuck at that point.
Tnx for any response.
This post is maybe longer but its super easy 5min done.
[2022 updated, still works, just config moved in another file, also people may return there because of higher Vue version ckeditor5 toolbar disappear and update/reinstall is needed]
This example is for full document type of ckeditor 5, decoupled-document is almost everything You need, just it lacks image-resize, to add it go to https://ckeditor.com/ckeditor-5/online-builder/ click it all way and add image-resize or all other fun stuff (You do not need premium Ckfinder, but You probably need CKFinder upload adapter for images uplad which is free), and download zip file, do not forget to pick same type in step 1 as one you will use/install.
Install (like in classic guide - https://ckeditor.com/docs/ckeditor5/latest/builds/guides/integration/frameworks/vuejs-v3.html)
npm install --save #ckeditor/ckeditor5-vue #ckeditor/ckeditor5-build-decoupled-document
(if here because of re-install, just remove package.json #ckeditor lines and run above install command again)
In main.js
import CKEditor from '#ckeditor/ckeditor5-vue';
createApp(App)
.use(router)
.use(CKEditor)
.mount("#app");
In your component
import DocumentEditor from '#ckeditor/ckeditor5-build-decoupled-document';
Now add config to data, You can find this config generated inside files you got from online-builder generator its copy/paste so do not freak out :) . You can find it in /src/ckeditor.js in defaultConfig, if you do not set it its possible You'll see an warning about missing "toolbar" options. Do not copy what you see below, use your custom generated config, its only for illustration :
data: function () {
return{
editorConfig: {
ckfinder: {
uploadUrl: 'https://page.com/api/uploadckeditor'
},
toolbar: {
items: [
'heading',
'|',
'bold',
'italic',
'link',
'bulletedList',
'numberedList',
'|',
'outdent',
'indent',
'|',
'imageUpload',
'blockQuote',
'insertTable',
'mediaEmbed',
'undo',
'redo',
'alignment',
'codeBlock',
'fontBackgroundColor',
'fontColor',
'fontFamily',
'fontSize',
'highlight',
'horizontalLine',
'htmlEmbed',
'imageInsert',
'pageBreak',
'removeFormat',
'strikethrough',
'underline',
'style'
]
},
language: 'cs',
image: {
toolbar: [
'imageTextAlternative',
'imageStyle:inline',
'imageStyle:block',
'imageStyle:side',
'imageStyle:alignLeft',
'imageStyle:alignRight',
'imageStyle:alignCenter',
'imageStyle:alignBlockLeft',
'imageStyle:alignBlockRight',
'linkImage'
]
},
table: {
contentToolbar: [
'tableColumn',
'tableRow',
'mergeTableCells',
'tableCellProperties',
'tableProperties'
]
},
fontFamily: {
options: [
'default',
'indieflowerregular',
'Arial, sans-serif',
'Verdana, sans-serif',
'Trebuchet MS',
'Apple Color Emoji',
'Segoe UI Emoji',
'Segoe UI Symbol',
]
},
licenseKey: ''
}
};
}
Now use it in component html
<ckeditor :editor="editor" #ready="onReady" v-model="editorData" :config="editorConfig"></ckeditor>
Decoupled component ckeditor package need #ready="onReady" othervise it will not initialize (classic do not need this)
here is method :
methods: {
onReady( editor ) {
// Insert the toolbar before the editable area.
editor.ui.getEditableElement().parentElement.insertBefore(
editor.ui.view.toolbar.element,
editor.ui.getEditableElement()
);
},
Ok now You have almost everything done just last magic thing to do .
In files you downloaded go to /build folder and COPY all the files into
"node_modules#ckeditor\ckeditor5-build-decoupled-document\build" and override initial decoupled-document. This is key thing to do, even thought it sounds pretty horrible.
Bonus : I wanted to have also image upload so added to config
**ckfinder: {
uploadUrl: 'http://mypage/api/uploadckeditor'
},**
Here is php side implementation its just basic one wit no error handling
$uploaddir = '../www/adminUpload/';
$uploadfile = $uploaddir . basename($_FILES['upload']['name']);
if (move_uploaded_file($_FILES['upload']['tmp_name'], $uploadfile)) {
//$this->sendJson(array("message"=>"sucess"));
} else {
//$this->sendJson(array("message"=>"failed"));
}
$returnArray = array();
$returnArray["uploaded"] = true;
$returnArray["url"] = "http://www.mypage.com/adminUpload/".$_FILES['upload']['name'];
header('Content-type: application/json');
$this->sendJson($returnArray);
$this->terminate();
For last 2 rows they are Nette php framework specific, just send out $returnArray as json response.
Here is how I integrated CKEDITOR with Vue3.js
Install required packages
npm install --save #ckeditor/ckeditor5-vue #ckeditor/ckeditor5-build-classic
main.ts
import CKEditor from '#ckeditor/ckeditor5-vue'
const app = createApp(App)
app.use( CKEditor ).mount('#app')
Then in your component where you wnat to use ckeditor
<template>
<ckeditor :editor="editor" v-model="data.description"></ckeditor>
</template>
<script>
import {onMounted, reactive, computed} from "vue"
import ClassicEditor from '#ckeditor/ckeditor5-build-classic'
export default{
name:'Add',
setup() {
//....
const data = reactive({
description: '',
})
return {
data,
editor: ClassicEditor
}
}
}
</script>
enter code here
I faced a problem image uploading inside ckeditor5-build-classic,
for image uploading I'm using Node.js server and S3, here is how returned the json response from Node.js server, uploaded flag is more important:
exports.upload_file_ckeditor = async(req, res) => {
let obj = {
"uploaded" : true,
"url" : 'http://example.com/upload/xyz.png'
}
return res.send(obj)
}

Laravel Voyager admin panel (tiny editor)

In my laravel voyager admin panel, the tiny editor is displaying as it is the source code, how can I eliminate the HTML tags and can only display the words?
go to config/voyager.php and add this code
'additional_js' => [
'js/custom.js',
],
now create a new file public/js/custom.js and add this code,
function tinymce_init_callback(editor) {
editor.remove();
editor = null;
tinymce.init({
selector: 'textarea.richTextBox',
skin: 'voyager',
min_height: 100,
height: 500,
resize: 'vertical',
inline_styles: false,
keep_styles: false,
font_formats: 'Open Sans, sans-serif',
plugins: 'print preview searchreplace autolink directionality visualblocks visualchars fullscreen image link media template codesample table charmap hr pagebreak nonbreaking anchor insertdatetime advlist lists textcolor wordcount imagetools contextmenu colorpicker textpattern code',
file_browser_callback: function (field_name, url, type, win) {
if (type == 'image') {
$('#upload_file').trigger('click');
}
},
toolbar: 'styleselect bold italic underline | forecolor backcolor | alignleft aligncenter alignright | bullist numlist outdent indent | link image table youtube giphy | code',
convert_urls: false,
image_caption: true,
image_title: true,
valid_elements: 'p[*],ul[*],li[*],ol[*],hr,br,img[*],-b,-i,-u,-h1,-h2,-h3,-h4,-h5,-h6',
valid_children: '+li[p]'
});
}
you can configure anything in this code.
It shows plugins not found
Failed to load plugin: template from url http://domain/admin/plugins/template/plugin.js net::ERR_ABORTED 404 (Not Found)

Resources