Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dataprocessor and XML (and other formats) #417

Closed
kikkauz opened this issue Mar 22, 2017 · 4 comments
Closed

Dataprocessor and XML (and other formats) #417

kikkauz opened this issue Mar 22, 2017 · 4 comments
Labels
type:question This issue asks a question (how to...).

Comments

@kikkauz
Copy link

kikkauz commented Mar 22, 2017

Hello

I hope I'm asking the question in the right place.
According to what I read here
https://github.com/ckeditor/ckeditor5-design/wiki/Data-Processing
I understand that it should be possible to have the server-side content in any format and that it is then possible to customize the "dataprocess process" to convert it in and out CKEditor.
This is something that really interests me as I'm asked to provide a wysiwyg online editor for structures XML content (with a complex schema).

But if I have a look to the xmlprocess file, for instance, it's hard for me to understand how I could extend or configure it to respond to my need.

Could someone please shed some light on this aspect of version 5? It looks very promising for me!

Thanks!

kikkauz

@Reinmar Reinmar changed the title dataprocessor and XML (and other formats) Dataprocessor and XML (and other formats) Mar 22, 2017
@Reinmar
Copy link
Member

Reinmar commented Mar 22, 2017

Hi, thanks for asking! :) This is a great question and something we've kept in mind for a long time, but never explained publicly.

Small disclaimer – some (most?) of the docs on https://github.com/ckeditor/ckeditor5-design/wiki/ are outdated because it turned out that maintaining even such a high-level docs takes an awful lot of time. So, this post takes precedence over what you can find in the design wiki. Fortunately, it shouldn't get outdated because we're very close to 1.0.0 now.


We're yet to write an architecture overview, but we need a quick intro about it to be able to answer your question.

This diagram shows (with some minor mistakes and outdated pieces) how the CKEditor 5 engine is structured:

CKEditor 5 engine's MVC architecture diagram

It's basically an MVC adjusted to the reality of text content editing.

  1. The editor listens to user actions through the editing view observers.
  2. Based on them, features make changes to the model (which uses a custom data structure, optimised for text editing and collaborative editing).
  3. The changes done to the model are converted (by features again) to the editing and data views (also called editing and data pipelines). These views are implemented using another custom data structure which resembles the DOM. There's a mistake on the diagram above – the view on the right should be called "data view". The editing view is responsible for editing operations – it's the document which the user sees. The data view (or rather – the data controller which governs the data pipeline) is responsible for data output (editor.getData()) and input (pasting, editor.setData()). It uses a data processor to convert view -> data and data -> view.

Now, the default features the editor provides (everything, even typing is a pluggable feature) make some assumptions regarding the type of the content (e.g. the heading feature assumes that you can only apply it to the entire paragraph, not a half of it, like in MSWord). Then, there's Schema which allows you and features to define some rules regarding the model (mostly, what's allowed where). Then, we have converters (provided by features) which transform the model to the view. The view, while not being yet what the user sees or the server gets, should be as close to the final structure (I don't mean the data format, just a... structure) as possible. Especially that the editing view is converted to the DOM (which the user sees) nearly 1:1 – the only difference is in "quirks" – a set of special changes needed by browsers. Of course, the editing pipeline is independent of the data pipeline, so the output data can be generated totally differently than the DOM you see when editing. Finally, we get to the data processor. Its job is to take the view (the data view) and produce some output format. It can be anything – string (HTML, XML, Markdown, RTF) or e.g. some serializable JavaScript object.

There are like dozen of levels on which you can modify the editor behaviour. There are very few limitation imposed by the engine – you can pick and choose from it, however, developing the engine took us already 3 years, so you can imagine that if you'd like to replace one part, it may be like a year of work :D.

Anyway, if you just need to output the content in a different data format (without changing the editing behaviour) you can just plug a different data processor. If you need to render things differently to the user, you need to work on converters. If you want to change what kind of content is allowed where (e.g. that bold can't be used in headings), you can use the schema. Finally, if some feature like typing should work differently (cause you need to impose special restrictions or something) you can tune up the existing typing feature (by listening on the model's #change events) or implement it from scratch.

I hope I answered your question or at least clarified a bit how it works. Let me know if something remained unclear :).

@Reinmar Reinmar added the type:question This issue asks a question (how to...). label Mar 22, 2017
@kikkauz
Copy link
Author

kikkauz commented Mar 22, 2017

Hi

wow, thanks for the prompt and very complete answer. I think I have to read it multiple times before understanding it completely :)

Anyway, the latest paragraph of your answer basically tells me everything I needed to know: we can render the XML in a human readable format, we can use the schema to control what is allowed and we can get back XML.
What is important is that I do not want to change the core code, I want to extend it in order to be able to follow CKeditor evolutions and bug fixes.

kikkauz

@fredck
Copy link
Contributor

fredck commented Mar 22, 2017

You may be interested in checking the (experimental) Markdown Data Processor:
https://github.com/ckeditor/ckeditor5-markdown-gfm/blob/master/src/gfmdataprocessor.js

The approach is pretty simple. It uses HTML as the intermediary format between the target format (Markdown) and the Data View. You may go the same way.

@Reinmar
Copy link
Member

Reinmar commented Apr 11, 2017

BTW, we miss an info how to easily plug in the data processor.

An editor instance stores the data processor instance under editor.data.processor. By default, it's set to HTMLDataProcessor so the editor accepts and outputs HTML string.

We didn't make it straightforward yet how to inject a different DP (see https://github.com/ckeditor/ckeditor5-core/issues/11), but most likely each DP will have an accompanying plugin which will enable it.

So, currently you can do this:

import MarkdownDP from '@ckeditor/ckeditor5-markdown-gfm/src/gfmdataprocessor';
import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classic';
import ArticlePreset from '@ckeditor/ckeditor5-presets/src/article';

// A plugin which will replace the default DP with MarkdownDP.
class MarkdownDPPlugin extends Plugin {
    constructor( editor ) {
        super( editor );
        
        editor.data.processor = new MarkdownDP();
    }
}

ClassicEditor.create( element, {
    plugins: [ ArticlePreset, MarkdownDPPlugin ]
} )
.then( ( editor ) => {
     console.log( editor );
} )
.catch( ( err ) => {
     console.error( err );
} );

I think it should do the job.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type:question This issue asks a question (how to...).
Projects
None yet
Development

No branches or pull requests

3 participants