I am (re)writing a plugin for CK editor 5. In version 4 i added HTML like this:
<span data-id="my-special-value" class="my-widget">My label</span>
I need the data-id value in PHP to do my stuff. But i can not figure out how to accomplish this in CKeditor 5.
CKeditor 5 works differently. It is very beautiful, but i still can`t find out how to add a widget like this with additional state (the data-id attribute).
I tried:
const viewFragment = editor.data.processor.toView(html);
const modelFragment = editor.data.toModel(viewFragment);
editor.model.insertContent( modelFragment );
My very basic conversioncode:
model.schema.register(pluginSlug, {
isBlock: false,
isObject: true,
allowContentOf: '$block',
allowWhere: [ '$block', '$text'],
});
// Retrieving the data from the editor.
editor.conversion.for('dataDowncast').add( downcastElementToElement( {
model: pluginSlug,
view: (modelItem, writer) => {
const element = writer.createContainerElement( 'span', { class: 'widget form-element-wysiwyg', test: "test" });
return element;
}
}) );
// Rendering the editor content to the user for editing.
editor.conversion.for('editingDowncast').add( downcastElementToElement( {
model: pluginSlug,
view: (modelItem, writer) => {
const element = writer.createContainerElement('span', { class: 'widget form-element-wysiwyg', test: "test" });
const widget = toWidget( element, writer, { label: 'Target Label' });
return widget;
}
}) );
// Loading the data to the editor.
editor.conversion.for('upcast').add( upcastElementToElement( {
view: {
name: 'span',
class: 'widget form-element-wysiwyg'
},
model: pluginSlug
}) );
I really can`t find out how to manage this. This code tries to add: <span data-id="my-special-value" class="my-widget">My label</span>
but now it still adds: <span class="my-widget">My label</span>
As you will see, it actually adds: <span class="my-widget" test="test">My label</span>
because of the dataDowncast code, but how to get my state from the insertContent code part?
A couple of quick advices:
allowWhere: [ '$block', '$text']
. You can't have a single element behaving like a block and like a text. You need to choose one – it's either inline or block. <span>
I guess "inline" is a better choice. In CKEditor 5 v12.0.0 (released a couple of days ago) we introduced support for inline widgets. Check out the implementing inline widget guide which covers a couple of things that you will need to know – especially the schema. view.class
. This is incorrect – there's only view.classes
. Plus, if you want to match against multiple classes you need to use an array. See https://ckeditor.com/docs/ckeditor5/latest/api/module_engine_conversion_upcasthelpers-UpcastHelpers.html#function-elementToElement and https://ckeditor.com/docs/ckeditor5/latest/api/module_engine_view_matcher-MatcherPattern.html downcastElementToElement()
and upcastElementToElement()
methods were moved to a different place in the document. Read more in the migration guide . Finally, the solution to how to upcast data-id
and store in the model is that the upcast converter needs to set it on the model element. Check out this example from UpcastHelpers#elementToElement()
:
editor.conversion.for( 'upcast' ).elementToElement( {
view: {
name: 'p',
classes: 'heading'
},
model: ( viewElement, modelWriter ) => {
return modelWriter.createElement( 'heading', { level: viewElement.getAttribute( 'data-level' ) } );
}
} );
As you can see, the model
part can be a callback returning a model element. It has access to the view element so you can read the attributes you need.
You can also do the same thing using UpcastHelpers#elementToElement()
and then UpcastHelpers#attributeToAttribute()
separately.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.