How to enable image upload support in CKEditor 5?

I will use ckeditor v5 in my project. I am trying to use the image plugin, but I do not find enough information about this.

If you see Demoe here , you can easily upload images using Drag & Drop. But when I try it with the loading ball, nothing will happen when I try to drag and drop the image. There are also no errors.

Is there any way to use this image support alternatively?

+9
source share
4 answers

Yes, image loading is included in all available assemblies. However, to make it work, you need to configure one of the existing download adapters or write your own. In short, the download adapter is a simple class whose role is to send the file to the server (in any way possible) and allow the returned promise as soon as it is executed.

You can read more in the official image upload guide or see a brief summary of the options available below.

Official Download Adapters

There are two built-in adapters:

  • For CKFinder , which require the installation of CKFinder connectors on your server.

    After installing the connector on your server, you can configure CKEditor to upload files to this connector by setting the config.ckfinder.uploadUrl parameter:

     ClassicEditor .create( editorElement, { ckfinder: { uploadUrl: '/ckfinder/core/connector/php/connector.php?command=QuickUpload&type=Files&responseType=json' } } ) .then( ... ) .catch( ... ); 

    You can also enable full integration with the CKFinder client file manager. Check out CKFinder integration examples and read more in the CKFinder Integration Guide .

  • For the Easy Image service, which is part of the CKEditor cloud services .

    You need to configure the cloud services account and after creating the token endpoint, configure the editor to use it:

     ClassicEditor .create( editorElement, { cloudServices: { tokenUrl: 'https://example.com/cs-token-endpoint', uploadUrl: 'https://your-organization-id.cke-cs.com/easyimage/upload/' } } ) .then( ... ) .catch( ... ); 

Disclaimer: This is a proprietary service.

Custom boot adapter

You can also write your own upload adapter, which will send files the way you want to your server (or where you want to send them).

For details on how to implement it, see the Custom image upload adapter Custom Image Upload Adapter Guide.

An example (that is, without built-in protection) of a boot adapter might look like this:

 class MyUploadAdapter { constructor( loader ) { // CKEditor 5 FileLoader instance. this.loader = loader; // URL where to send files. this.url = 'https://example.com/image/upload/path'; } // Starts the upload process. upload() { return new Promise( ( resolve, reject ) => { this._initRequest(); this._initListeners( resolve, reject ); this._sendRequest(); } ); } // Aborts the upload process. abort() { if ( this.xhr ) { this.xhr.abort(); } } // Example implementation using XMLHttpRequest. _initRequest() { const xhr = this.xhr = new XMLHttpRequest(); xhr.open( 'POST', this.url, true ); xhr.responseType = 'json'; } // Initializes XMLHttpRequest listeners. _initListeners( resolve, reject ) { const xhr = this.xhr; const loader = this.loader; const genericErrorText = 'Couldn\'t upload file:' + ' ${ loader.file.name }.'; xhr.addEventListener( 'error', () => reject( genericErrorText ) ); xhr.addEventListener( 'abort', () => reject() ); xhr.addEventListener( 'load', () => { const response = xhr.response; if ( !response || response.error ) { return reject( response && response.error ? response.error.message : genericErrorText ); } // If the upload is successful, resolve the upload promise with an object containing // at least the "default" URL, pointing to the image on the server. resolve( { default: response.url } ); } ); if ( xhr.upload ) { xhr.upload.addEventListener( 'progress', evt => { if ( evt.lengthComputable ) { loader.uploadTotal = evt.total; loader.uploaded = evt.loaded; } } ); } } // Prepares the data and sends the request. _sendRequest() { const data = new FormData(); data.append( 'upload', this.loader.file ); this.xhr.send( data ); } } 

Which can then be turned on as follows:

 function MyCustomUploadAdapterPlugin( editor ) { editor.plugins.get( 'FileRepository' ).createUploadAdapter = ( loader ) => { return new MyUploadAdapter( loader ); }; } ClassicEditor .create( document.querySelector( '#editor' ), { extraPlugins: [ MyCustomUploadAdapterPlugin ], // ... } ) .catch( error => { console.log( error ); } ); 

NOTE. The above is an example of a boot adapter. As such, it does not have built-in security mechanisms (such as CSRF protection).

+17
source

I was looking for information on how to use this control, and found the official documentation is pretty minimal. However, after much trial and error, I made it work, so I thought I'd share it.

In the end, I used the simple CKEditor 5 boot adapter with Angular 8, and it works just fine. However, you need to create a custom ckeditor assembly with the download adapter installed. This is pretty easy to do. I assume that you already have Angular ckeditor files.

First create a new angular project directory and name it "cKEditor-Custom-Build" or something like that. Do not run ng new (Angular CLI), but use npm instead to get the base assembly of the editor you want to show. For this example, I use the classic editor.

 https://github.com/ckeditor/ckeditor5-build-classic 

Go to github and clone or upload the project to a new brilliant build directory.

if you use VS code, open the directory, open a terminal window and get the dependencies:

 npm i 

Now you have the basic assembly, and you need to install the adapter to boot. CkEditor has one. install this package to get a simple download adapter:

 npm install --save @ckeditor/ckeditor5-upload 

.. as soon as this is done, open the ckeditor.js file in the project. This is in the src directory. If you played with ckEditor, then its contents should look familiar.

Import the new js file into the ckeditor.js file. There will be a whole bunch of imports in this file, and they will go all the way down.

 import SimpleUploadAdapter from '@ckeditor/ckeditor5-upload/src/adapters/simpleuploadadapter'; 

... Then add the import to your array of plugins. Since I use the classic editor, my section is called "ClassicEditor.builtinPlugins", add it next to the TableToolbar. This is all set up. No additional toolbars or settings are needed for this.

Create your ckeditor-custom-build.

 npm run build 

The magic of Angular will do the trick, and the build directory will be created in your project. Here it is for custom assembly.

Now open your angular project and create a directory for the new assembly. I actually put mine in a resource subdirectory, but it can be anywhere you can link to it.

Create a directory in "src / assets" called something like "ngClassicEditor", no matter what you call it, and copy the assembly file (that you just created) into it. Then, in the component that you want to use in the editor, add the import statement with the path to the new assembly.

 import * as Editor from '@app/../src/assets/ngClassicEditor/build/ckeditor.js'; 

almost done...

The final bit is to configure the download adapter with the API endpoint that the adapter must use to download images. Create a config in your component class.

  public editorConfig = { simpleUpload: { // The URL that the images are uploaded to. uploadUrl: environment.postSaveRteImage, // Headers sent along with the XMLHttpRequest to the upload server. headers: { 'X-CSRF-TOKEN': 'CSFR-Token', Authorization: 'Bearer <JSON Web Token>' } } 

};

I actually use environment conversion here when the URI changes from dev to production, but you can hardcode the direct URL if you want.

The last part is to configure your editor in the template to use the new configuration values. Open component.html and change the ckeditor editor tag.

  <ckeditor [editor]="Editor" id="editor" [config]="editorConfig"> </ckeditor> 

Here it is. You made. test, test test.

My API is the .Net API, and I am happy to share it if you need some sample code. I really hope this helps.

+1
source

@ Darren Street .. Hello Darren. I took every step you wrote, but I get

"Cannot read property 'rootName' of undefined" in ckeditor-ckeditor5-angular.js

I tried to find a solution, but I can not get the correct information or instructions for this error. Maybe you have an idea what could be wrong?

0
source

Fast start

 npm install --save @ckeditor/ckeditor5-angular 

Install one of the official editor assemblies or create your own.

Assuming you selected @ ckeditor / ckeditor5-build-classic:

 npm install --save @ckeditor/ckeditor5-build-classic 

Now add the CKEditorModule to your application import module:

 import { CKEditorModule } from '@ckeditor/ckeditor5-angular'; @NgModule( { imports: [ CKEditorModule, // ... ], // ... } ) 

ckeditorEx.html:

  <ckeditor [config]="editorConfig" [editor]="Editor" [(ngModel)]="description" #desc="ngModel" spellcheck="false" required minlength="50" name="editor5" (ready)="onReady($event)"> </ckeditor> 

component.ts

 onReady($event) { $event.plugins.get('FileRepository').createUploadAdapter = (loader) => { return new MyUploadAdapter(loader); 

};

I already did this in one of my projects, and I posted a tutorial on this topic on my blog https://www.stackquery.com/articles/how-to-implement-ckeditor5-in-angular-and-upload-image- to-asp-net-core-web-api / 60e91802-94ed-430d-ab5e-66c33f9babb7 The tutorial contains step-by-step instructions and a complete implementation of how to implement CKEditor5 with image loading.

0
source

Source: https://habr.com/ru/post/1272652/


All Articles