Multiple Ckeditor inline editors with custom toolbar - javascript

I currently have a page with about 13 text area boxes and each has their inline editor defined. The default tool bar is full but I would like the change the default toolbar layout for all my inlines, to only keep the needed buttons/functionality.
Here is my script, how would I be able to reference to a custom toolbar?
<script>
CKEDITOR.inline( 'inline_editor1' );
CKEDITOR.inline( 'inline_editor2' );
CKEDITOR.inline( 'inline_editor3' );
CKEDITOR.inline( 'inline_editor4' );
CKEDITOR.inline( 'inline_editor5' );
CKEDITOR.inline( 'inline_editor6' );
CKEDITOR.inline( 'inline_editor7' );
CKEDITOR.inline( 'inline_editor8' );
CKEDITOR.inline( 'inline_editor9' );
CKEDITOR.inline( 'inline_editor10' );
CKEDITOR.inline( 'inline_editor11' );
CKEDITOR.inline( 'inline_editor12' );
CKEDITOR.inline( 'inline_editor13' );
</script>

You can give each CKEDITOR instance a different config object as can be seen at http://docs.ckeditor.com/#!/api/CKEDITOR-method-inline and you can define a custom toolbar for each configuration option as seen here: http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-toolbar
So, you could have something like this untested code:
<script>
var cfg1 = { toolbar: 'Basic' };
var cfg2 = { toolbar: 'Full' };
var cfg3 = {
uiColor: '#FF69B4',
toolbar: [
[ 'Source', '-', 'Bold', 'Italic' ]
]
};
CKEDITOR.inline( 'inline_editor1', cfg1 );
CKEDITOR.inline( 'inline_editor2', cfg2 );
CKEDITOR.inline( 'inline_editor3', cfg3 );
</script>

Related

Custom Server-rendered Gutenberg block does not always render

I have written a plugin that provides a custom "Server Side Block" that uses a callback defined in PHP that is supposed to render some HTML.
The right markup renders in certain case, but in others I just get the comment <!-- wp:nai/serverside /-->.
It happens mainly when I put other blocks in the page, or I put my custom block inside another.
What is wrong? Why can't I put the block wherever I want without breaking it?
Here is the code:
plugin.php:
<?php
/**
* #package MyPlugin
*/
/*
Plugin Name: My Plugin
Version: 1.7.2
*/
function gutenberg_examples_01_register_block() {
// automatically load dependencies and version
$asset_file = include( plugin_dir_path( __FILE__ ) . 'build/index.asset.php');
wp_register_script(
'serverside',
plugins_url( 'build/index.js', __FILE__ ),
$asset_file['dependencies'],
$asset_file['version']
);
wp_register_style(
'herverside',
plugins_url( 'style.css', __FILE__ ),
array( ),
filemtime( plugin_dir_path( __FILE__ ) . 'style.css' )
);
register_block_type('nai/serverside', array(
'editor_script' => 'serverside',
'render_callback' => 'render_callback',
'attributes' => array(
'images' => array(
'type' => 'array'
)
)
)
);
function render_callback( $attributes ){
//$images = $attributes[ 'images' ];
return '<div>Test</div>';
}
}
add_action( 'init', 'gutenberg_examples_01_register_block' );
src/index.tsx:
declare var wp;
const { __ } = wp.i18n;
const { registerBlockType } = wp.blocks;
const el = wp.element.createElement;
const blockStyle = {
backgroundColor: '#900',
color: '#fff',
padding: '20px',
};
registerBlockType( 'nai/serverside', {
title: __( 'Server Side Block', 'text-domain' ),
icon: 'networking',
category: 'common',
attributes: {
images : {
default: [],
type: 'array',
}
},
edit({attributes, setAttributes, className, focus, id}) {
return (
<div style={ blockStyle }>
Not visible in editor mode.
</div>
);
},
save({attributes, className}) {
/*return (
<div style={ blockStyle }>
Hello World, step 1 (from the frontend).
</div>
);*/
return null;
},
} );

React js: Image upload is not working in CKEditor

CKEditor image upload is not working and below is the code
<CKEditor
editor={ ClassicEditor }
data={this.state.miscNotesData.miscnote}
onInit={ editor => {
// You can store the "editor" and use when it is needed.
console.log( 'Editor is ready to use!', editor );
} }
onChange={ ( event, editor ) => {
const data = editor.getData();
this.handleChange(data);
console.log( { event, editor, data } );
} }
/>
Error:
backend.js:6 filerepository-no-upload-adapter: Upload adapter is not defined.
Read more: https://ckeditor.com/docs/ckeditor5/latest/framework/guides/support/error-codes.html#error-filerepository-no-upload-adapter
As provided in documentation https://ckeditor.com/docs/ckeditor5/latest/features/image-upload/image-upload.html
there are 4 options to upload images in CKEDitor: Easy Image(proprietary), CKFinder(needs connector on PHP or ASP.net), Simple adapter, Base64 adapter
I use Simple adapter for this purpose with Node js server:
First, I installed SimpleUploadAdapter in ClassicEditor, then I set up config in CKEditor:
<CKEditor
data={input.value}
editor={ ClassicEditor }
config={{
simpleUpload: {
uploadUrl: 'https://myserver.herokuapp.com/image-upload'
},
toolbar: ['heading', '|', 'bold', 'italic', 'blockQuote', 'link', 'numberedList', 'bulletedList', 'imageUpload', 'insertTable',
'tableColumn', 'tableRow', 'mergeTableCells', 'mediaEmbed', '|', 'undo', 'redo']
}}
/>
And create url on my server /image-upload

Create non editable block with text in CKEditor 5

How do I Create a non editable block with text in CKEditor 5.
I need something which in the final view generate a:
<div>Non editable message here</div>
I tried to use a UIElement and then set innerHTML but that still makes the element editable.
Just for reference: Her is the plugin I ended up using.
import Plugin from '#ckeditor/ckeditor5-core/src/plugin';
import DecoupledEditor from '#ckeditor/ckeditor5-editor-decoupled/src/decouplededitor';
import Essentials from '#ckeditor/ckeditor5-essentials/src/essentials';
import Paragraph from '#ckeditor/ckeditor5-paragraph/src/paragraph';
import Bold from '#ckeditor/ckeditor5-basic-styles/src/bold';
import Heading from '#ckeditor/ckeditor5-basic-styles/src/bold';
import Italic from '#ckeditor/ckeditor5-basic-styles/src/italic';
import ButtonView from '#ckeditor/ckeditor5-ui/src/button/buttonview';
import imageIcon from '#ckeditor/ckeditor5-core/theme/icons/image.svg';
import Command from '#ckeditor/ckeditor5-core/src/command';
import { downcastElementToElement,downcastAttributeToAttribute,downcastAttributeToElement } from '#ckeditor/ckeditor5-engine/src/conversion/downcast-converters';
import { upcastElementToElement, upcastAttributeToAttribute,modelToViewAttributeConverter} from '#ckeditor/ckeditor5-engine/src/conversion/upcast-converters';
import attachPlaceholder from "#ckeditor/ckeditor5-engine/src/view/placeholder";
import ViewPosition from '#ckeditor/ckeditor5-engine/src/view/position';
import toWidgetEditable from '#ckeditor/ckeditor5-widget/src/utils';
import ClickObserver from '#ckeditor/ckeditor5-engine/src/view/observer/clickobserver';
import UpcastDispatcher from '#ckeditor/ckeditor5-engine/src/conversion/upcastdispatcher';
import { toWidget } from '#ckeditor/ckeditor5-widget/src/utils';
export default class TestWidget2 extends Plugin {
static get pluginName() {
return 'TestWidget2';
}
init() {
console.log('TestWidget2::init()');
const editor=this.editor;
const model=editor.model;
model.schema.register( 'myWidget', {
inheritAllFrom: '$block',
isObject: true
} );
editor.conversion.for( 'dataDowncast' )
.add( downcastElementToElement( {
model: 'myWidget',
view: ( modelItem, writer ) => {
const elm=writer.createContainerElement( 'div', { class: 'widget' } );
return toWidget( div, writer, { label: 'widget label' } );
}
} ) );
editor.conversion.for( 'editingDowncast' )
.add( downcastElementToElement( {
model: 'myWidget',
view: ( modelItem, writer ) => {
const div = writer.createContainerElement( 'div', { class: 'widget' } );
return toWidget( div, writer, { label: 'widget label' } );
}
} ) );
editor.conversion.for( 'upcast' )
.add( upcastElementToElement( {
view: {
name: 'div',
class: 'widget'
},
model: 'myWidget'
} ) );
}
}
You can create the widget API for that:
import Widget from '#ckeditor/ckeditor5-widget/src/widget';
import { toWidget } from '#ckeditor/ckeditor5-widget/src/utils';
import { downcastElementToElement } from '#ckeditor/ckeditor5-engine/src/conversion/downcast-converters';
import { upcastElementToElement } from '#ckeditor/ckeditor5-engine/src/conversion/upcast-converters';
ClassicEditor
.create( document.querySelector( '#editor' ), {
plugins: [ Essentials, Paragraph, Widget, /* ... other plugins ... */ ],
toolbar: [ 'undo', 'redo' ]
} )
.then( editor => {
window.editor = editor;
const model = editor.model;
model.schema.register( 'myWidget', {
inheritAllFrom: '$block',
isObject: true
} );
editor.conversion.for( 'dataDowncast' )
.add( downcastElementToElement( {
model: 'myWidget',
view: ( modelItem, writer ) => {
return writer.createContainerElement( 'div', { class: 'widget' } );
}
} ) );
editor.conversion.for( 'editingDowncast' )
.add( downcastElementToElement( {
model: 'myWidget',
view: ( modelItem, writer ) => {
const div = writer.createContainerElement( 'div', { class: 'widget' } );
return toWidget( div, writer, { label: 'widget label' } );
}
} ) );
editor.conversion.for( 'upcast' )
.add( upcastElementToElement( {
view: {
name: 'div',
class: 'widget'
},
model: 'myWidget'
} ) );
editor.setData(
'<p>foobar</p>' +
'<div class="widget">Non editable text goes here</div>' +
'<p>foobar</p>'
);
} )
.catch( err => {
console.error( err.stack );
} );
The key point is to use the toWidget() function when downcasting an element to the editing view. Also, that element should be marked as an object in the schema.
Also don't forget to load the Widget plugin which turns on the support for widgets.
I just had the problem yesterday that when having a html table inside the isObject widget content, the table was still editable and also had controls.
The only way to fix it was to disable interaction inside my widget via css.
.ck-widget.my-wdiget *:not(.ck.ck-reset_all.ck-widget__type-around) {
pointer-events: none;
}
.ck.ck-reset_all.ck-widget__type-around is the class of the widget controls to add a linebreak before or after the widget. They are still usable.
I followed your steps without success..
For better knowledge (this guideline it's tested only in custom build for angular application but i think thats work everywhere)
probably you need use this command for follow correctly this guideline
npm install -g webpack
and in add to this you need install globally another dependency but i don't remember what is! (you can easly search the error on google for find it)
Create your custom build here
unzip, open folder and run npm install
install widget(with type def. if necessary) and core dependencies
npm i --save -D #ckeditor/ckeditor5-widget
npm i --save -D #types/ckeditor__ckeditor5-widget
npm i --save -D #ckeditor/ckeditor5-core
go into path src/ckeditor.js and add the following code for create the reinmar custom plugin
import {toWidget, Widget} from "#ckeditor/ckeditor5-widget";
import Plugin from '#ckeditor/ckeditor5-core/src/plugin';
class NotEditable extends Plugin {
init() {
const editor = this.editor;
const model = editor.model;
model.schema.register('myWidget', {
inheritAllFrom: '$block',
isObject: true
});
editor.conversion.for('dataDowncast')
.elementToElement({
model: 'myWidget',
view: (modelItem, writer) => {
return writer.writer.createContainerElement('div', {class: 'widget'});
}
});
editor.conversion.for('editingDowncast')
.elementToElement({
model: 'myWidget',
view: (modelItem, writer) => {
const div = writer.writer.createContainerElement('div', {class: 'widget'});
return toWidget(div, writer.writer, {label: 'widget label'});
}
});
editor.conversion.for('upcast')
.elementToElement({
view: {name: 'div', class: 'widget'},
model: 'myWidget'
});
}
}
and in Editor.builtinPlugins add Widget and NotEditable
Editor.builtinPlugins = [
//***other plugin,
Widget,
NotEditable
];
exec in the terminal npm run build
copy the build folder into your project and import the build (follow official Ckeditor5 guideline for this) {in my case i follow this guideline in angular guide}
According to the documentation isReadOnly : Boolean
Set it to true.
Official Documentation

CKeditor copy inline widget from editable widget (Firefox)

I am facing a problem in CKeditor (4.8.0) copy/paste on firefox for inline widget inside editable widget. Here is my fiddle
I want to copy both text and inline widget from the editable part of another widget :
But when i am pasting it only the start of the text is copied until the widget start :
This is working on Chrome
Html :
<textarea id="editor">foo bar
<div class='mywidget'>
<div>Header</div>
<div class='mywidget_contents'>
<p>test copy <span class="cke_placeholder">[[it]]</span> please<br></p>
</div>
</div>
</textarea>
Javascript :
CKEDITOR.plugins.add( 'mywidget', {
requires: 'widget',
icons: 'mywidget',
init: function( editor ) {
editor.widgets.add( 'mywidget', {
button: "My Widget",
template:"<div class='mywidget'><div>Header</div><div class='mywidget_contents'></div></div>",
editables: {
content: {
selector: '.mywidget_contents'
}
},
upcast: function (element) {
return element.hasClass('mywidget');
}
} );
}
} );
CKEDITOR.replace( 'editor', {
extraPlugins: 'mywidget,placeholder'
} );
Did someone find a workaround for this ?

How to customize ckeditor toolbar button behavior?

In ckeditor 4.0.1 in when "text direction from left to right" toolbar button is pushed, i type hello, the generated HTML source is:
<p dir="ltr">hello</p>
how can i change this behavior so that the generated source is look like:
<p dir="ltr" style="text-align: left;">hello</p>
Thanks in advance.
You can do this with dataProcessor:
CKEDITOR.replace( 'editor1', {
on: {
instanceReady: function () {
this.dataProcessor.htmlFilter.addRules( {
elements: {
p: function( element ) {
if ( element.attributes.dir == 'ltr' )
element.attributes.style = 'text-align: left;';
}
}
});
}
}
} );
You can also add it globally:
CKEDITOR.on( 'instanceReady', function ( event ) {
event.editor.dataProcessor.htmlFilter.addRules( {
elements: {
p: function( element ) {
if ( element.attributes.dir == 'ltr' )
element.attributes.style = 'text-align: left;';
}
}
});
} );

Categories

Resources