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

How to integrate Base64 or Simple file upload? #126

Closed
deadmann opened this issue Jul 28, 2019 · 16 comments
Closed

How to integrate Base64 or Simple file upload? #126

deadmann opened this issue Jul 28, 2019 · 16 comments
Labels
resolution:resolved This issue was already resolved (e.g. by another ticket). type:question

Comments

@deadmann
Copy link

First thing, it seem this issue uses another packages: #88

Packages i install:
ckeditor5-
adapter-ckfinder
angular
build-classic
build-decoupled-document
ckfinder
core
editor-decoupled
engine
ui
upload
utils

in the upload i found: base64uploadadapter.js

Another thing... i have no idea how config work, how to add simple plugin, how to manythings, how js based sample can be converted to angular.

Here's my code:

import { Component, OnInit } from '@angular/core';
import * as ClassicEditor from '@ckeditor/ckeditor5-build-classic';
import * as DecoupledEditor from '@ckeditor/ckeditor5-build-decoupled-document';
import Base64UploadAdapter from '@ckeditor/ckeditor5-upload/src/base64uploadadapter';
import { FormBuilder, Validators, FormGroup, ValidationErrors } from '@angular/forms';
import { Util } from 'leaflet';
import { environment } from 'src/environments/environment';
import { Utility } from 'src/_utility/Utility';

@Component({
  selector: 'app-story-insert',
  templateUrl: './story-insert.component.html',
  styleUrls: ['./story-insert.component.less']
})
export class StoryInsertComponent implements OnInit {
  util = Util;

  public ckEditor = DecoupledEditor; // ClassicEditor;

  insertForm: FormGroup;

  envValidators = environment.validations;

  public onReady( editor ) {
    editor.ui.getEditableElement().parentElement.insertBefore(
        editor.ui.view.toolbar.element,
        editor.ui.getEditableElement()
    );

    // tslint:disable-next-line:max-line-length
    // Only useful source: https://stackoverflow.com/questions/52052514/upload-adapter-is-not-defined-issue-with-image-uploading-in-ckeditor5-angular/55237874#55237874
    editor.plugins.get('FileRepository').createUploadAdapter = (loader) => {
      console.log(btoa(loader.file));
      return new Base64UploadAdapter(loader); // UploadAdapter(loader);
    };
  }

  constructor(private fb: FormBuilder) { }

  ngOnInit() {
    this.insertForm = this.fb.group({
      title: ['', [Validators.required, Validators.maxLength(this.envValidators.titleMaxLength)]],
      description: ['', [Validators.required, Validators.maxLength(this.envValidators.descriptionMaxLength)]],
      keywords: ['', [Validators.required, Validators.maxLength(this.envValidators.articleKeywordMaxLength)]],
      articleContent: ['']
    }, {
      validators: [this.ckEditorArticleValidator('articleContent')]
    });
  }

  public ckEditorArticleValidator(ckEditorField: string): (g: FormGroup) => ValidationErrors | null {
    const validator = (g: FormGroup): ValidationErrors | null => {
      const ckEditorCtrl = g.get(ckEditorField);
      if (Utility.isNullOrUndefinedOrWhiteSpace(ckEditorCtrl.value)) {
        return {ckeditor_required: true};
      } else if (ckEditorCtrl.value.length > 4000) {
        return {ckeditor_maxlength: true};
      }
      return null;
    };
    return validator;
  }

  insertStory(): void {

  }



  get title() {
    return this.insertForm && this.insertForm.get('title');
  }
  get description() {
    return this.insertForm && this.insertForm.get('description');
  }
  get keywords() {
    return this.insertForm && this.insertForm.get('keywords');
  }
  get articleContent() {
    return this.insertForm && this.insertForm.get('articleContent');
  }
}

I get this error:

log.js:58 ckeditor-duplicated-modules: Some CKEditor 5 modules are duplicated. Read more: https://ckeditor.com/docs/ckeditor5/latest/framework/guides/support/error-codes.html#error-ckeditor-duplicated-modules
undefined

After click and upload image, i get this error:

TypeError: this._adapter.upload is not a function

@Mgsy
Copy link
Member

Mgsy commented Jul 29, 2019

If you want to add plugins to the editor, you should create a custom build, then import it to your project instead of ckeditor5-build-classic. Please, see our Installing plugins guide.

Update:

The easiest way to set the upload adapter or to add / remove plugin from the build is by creating a custom build via the CKEditor 5 Online Builder that includes your own set of plugins. Then, you should follow the CKEditor 5 Angular integration - custom build section.

@Mgsy Mgsy added pending:feedback This issue is blocked by necessary feedback. type:question labels Jul 29, 2019
@deadmann

This comment has been minimized.

@deadmann deadmann reopened this Jul 30, 2019
@ma2ciek

This comment has been minimized.

@Mgsy Mgsy closed this as completed Aug 13, 2019
@Mgsy Mgsy added resolution:fixed and removed pending:feedback This issue is blocked by necessary feedback. labels Aug 13, 2019
@ma2ciek

This comment has been minimized.

@nbittich
Copy link

nbittich commented May 2, 2020

why do i have to clone your code and do a custom build just to add that plugin... this is ridiculous...

edit: ok i just copy pasted your code into my project... just 1 hour with your library and i already want to throw it and do it myself. why such complexity? i don't want to read your doc totally before starting to work... that's not how it works in 2020. in 2020 the getting start guide should be enough to cover 90% of the cases. then if the library is great we go deep to the doc, to customize as we want. i just started to read your doc and i already want to give up. "in order to do a simple thing start cloning our code first" why?! "read our 5000 pages of doc to understand how our textarea works" ... you don't like developers dude. you are just like the people who created so many bad games on NES and master system when we were kids, just to make us suffer for nothing.

@ma2ciek
Copy link
Contributor

ma2ciek commented May 4, 2020

why do i have to clone your code and do a custom build just to add that plugin... this is ridiculous...

edit: ok i just copy pasted your code into my project... just 1 hour with your library and i already want to throw it and do it myself. why such complexity? i don't want to read your doc totally before starting to work... that's not how it works in 2020. in 2020 the getting start guide should be enough to cover 90% of the cases. then if the library is great we go deep to the doc, to customize as we want. i just started to read your doc and i already want to give up. "in order to do a simple thing start cloning our code first" why?! "read our 5000 pages of doc to understand how our textarea works" ... you don't like developers dude. you are just like the people who created so many bad games on NES and master system when we were kids, just to make us suffer for nothing.

  1. The thing is complicated because of the specific Angular ecosystem and our plugin separation. We can't currently compile CKEditor 5 sources with Angular sources because the Angular webpack plugin and loaders conflict with CKEditor 5 set of webpack plugin and loaders needed to attach. Notabene, CKEditor5 has introduced CSS and SVG imports to provide a way for customizing the output and easily maintaining it (like extracting CSS from added plugins to the separate files instead of the bundle, etc). With old Angular's extracting webpack config this would be solvable at this point.
  2. The CKEditor 5 architecture is very modular. You don't get everything bundled into one package because it would weight a couple of MB and nobody would be happy to attach such file in the web. BTW - what to do with conflicting packages? Like Base64 upload adapter and Simple upload adapter, easy image adapter, CKFinder adapter and so on...
  3. There're predefined CKEditor 5 builds. They're a little bit pain in the ass as they are limited and everybody has different needs and rebuilding with new plugins aren't easy. I have to agree with you that they produce highly negative DX.
  4. There's an online builder tool that was created to ease the whole process. Use it if you don't want to customize the editor deeply. https://ckeditor.com/ckeditor-5/online-builder/ It will take less than 1 minute ot get ready to use CKEditor 5 build with your plugins.

I'll hide my previous response as it's outdated a little bit. Use CKEditor 5 Online builder instead.

@ma2ciek
Copy link
Contributor

ma2ciek commented May 4, 2020

I updated the solution - #126 (comment).

@nbittich
Copy link

nbittich commented May 4, 2020

Thank you for the quick reply. I switched to quill, and it works as I want so far (base64 images out of the box):

image

Also the buttons are responsive out of the box( had an issue with that with ckEditor 5 ):

image

I understand your reasons but imo it should be different. First of all, I took the "Document" build, and the upload image icon is there by default in the toolbox. So I imagine that the plugin should be there as well.

I'm a backend developer, so I'm not an expert with webpack, I have to admit it. But for other libraries, I'm used to do stuff like:
npm install @ckEditor/angular-plugin-file-base-64

then in my imports: ImageBase64Module.

That makes more sense imo. I will have a look to the online builder, but I don't like this solution, because then I have to manage your project somewhere on a git repo. This would produce issue:

-> how do I align my version with the default one, in case of bug fixing for instance?

Another solution would be to define interfaces that we can implement. I couldn't find an interface like "Plugin" in the document build, althought it would be very useful. Then I know what's expected from the plugin management system.

The toolbar for each build should be minimalistic if you don't bundle the according plugins, at least a default one. Because we think if it's there, then it's part of the build. but it's not.

Thanks for the reply again, CkEditor looks like a great product, but for proof of concept like I'm doing now, it doesn't fit. Developer experience can definitely be improved.

@ma2ciek
Copy link
Contributor

ma2ciek commented May 4, 2020

Thanks for the feedback!

I understand your reasons but imo it should be different. First of all, I took the "Document" build, and the upload image icon is there by default in the toolbox. So I imagine that the plugin should be there as well

The plugin for handling image inside the editor is built-in to all builds. However the "upload" part which requires the Image plugin can be defined in various ways. Thus why there's an image button, but there's no image adapter set. Actually, the base64 could be the default one, but uploading a few images would blow up your data and while it makes sense for PoCs it doesn't make sense for larger apps.

I'm a backend developer, so I'm not an expert with webpack, I have to admit it. But for other libraries, I'm used to do stuff like:
npm install ckEditor/angular-plugin-file-base-64

Yes... It works this way in our React and Vue integrations. But because of the mentioned issue with Angular loaders incompatibility and no way to configure the webpack for the Angular's app there's currently no way to do that. I know it's a big pain. But the CKEditor 5 wasn't developed for Angular ecosystem. It's a pure Vanilla JS editor. Unfortunately, we added two loaders needed to compile our sources - SVG loader and (Post)CSS loaders to not write everything in the JS files and to be able to reuse some parts of the UI, plus be able to configure the output. That's actually a bit PITA in the JS ecosystem. There're many "standards" that are conflicting. with only one default loader for CSS and SVG that problem wouldn't exist.

That makes more sense imo. I will have a look to the online builder, but I don't like this solution, because then I have to manage your project somewhere on a git repo. This would produce issue:

-> how do I align my version with the default one, in case of bug fixing for instance?

There're a few tools like `npm-check-updates` and similar ones which can update picked dependencies to latest ones. We'll also provide a tool to download an updated version of your packages from the CKEditor 5 Online Builder tool.

Another solution would be to define interfaces that we can implement. I couldn't find an interface like "Plugin" in the document build, althought it would be very useful. Then I know what's expected from the plugin management system.

Have you seen the https://ckeditor.com/docs/ckeditor5/latest/framework/guides/creating-simple-plugin.html and Plugin interface? There's also the Plugin base class, which you can use to inherit some useful methods from it.

Thanks for the reply again, CkEditor looks like a great product, but for proof of concept like I'm doing now, it doesn't fit. Developer experience can definitely be improved.

I think that the core of the problem is that it doesn't work out of the box. But there're a few reasons why it currently behaves differently.

@ma2ciek
Copy link
Contributor

ma2ciek commented May 4, 2020

Also the buttons are responsive out of the box( had an issue with that with ckEditor 5 ):

Could you tell more about it? And could you create an issues in the CKEditor 5 issue tracker?

@nbittich
Copy link

nbittich commented May 4, 2020

Hey,
Sorry I didn't create a issue on github because I didn't go further but here it is:

image

As you see, the toolbar goes outside the window in case of mobile device; maybe it's not a bug, I am not sure; also there is no borders on the textarea part;

Step to reproduce:

 npm install --save @ckeditor/ckeditor5-angular
 npm i @ckeditor/ckeditor5-build-decoupled-document

app.module.ts:


  imports: [
    ...,
    CKEditorModule
  ]

document.component.ts:


 public Editor = DecoupledEditor;

  public onReady( editor ) {
    editor.ui.getEditableElement().parentElement.insertBefore(
      editor.ui.view.toolbar.element,
      editor.ui.getEditableElement()
    );
  }

document.component.html:


<ckeditor [editor]="Editor" data="<p>Hello, world!</p>" (ready)="onReady($event)"></ckeditor>

@nbittich
Copy link

nbittich commented May 4, 2020

if you confirm it's a bug i'll create a ticket np, btw it is the hello world example, i didn't try to customize anything

@nbittich
Copy link

nbittich commented May 4, 2020

For the base64 images I can live with it because I'm storing the document as an html page on the disk (server side), I just have a reference to the file in the database (mongodb); I could use GridFS to store it with mongo but I was too lazy yesterday haha. Also I don't think the document will contains tons of images, so I can live with my solution. For the Plugin interface, I couldn't find it in the npm packages I've installed (same as the hello world example), I think I had to make a custom build anyway to get that interface; Managing an external dependency is not something I did often during my carreer , 7y doing backend dev. I did it two times yes, it wasn't my idea and i didn't like it (and we end up having issues with that). I see external deps as black boxes. Having it on a private repo means that if a developer starts working on my project, he has to clone two projects and not one. or I could have my own npm registry, but all those steps equals less productive work imo. I'll try it again once my POC is over, lots of nice plugins there, maybe i'll switch to react or vue (the nice thing when being backend dev is to be completely open for changes on the frontend framework :D i like vuejs for its simplicity, maybe the experience will be better with it)

@robert-lara
Copy link

I assume people are still ending up here trying to figure out how to integrate this all into an Angular Application, specifically with the simpleFileUpload plugin. I made a sample repo of this being done using the custom build tool CKEditor offers and added the steps in the README, cheers!

CKEditor5 with Angular and SimpleFileUploader Plugin

@hexdecimal16
Copy link

Getting this error when using online builder to build with custom plugins.

core.js:5980 ERROR Error: Uncaught (in promise): CKEditorError: ckeditor-duplicated-modules
Read more: https://ckeditor.com/docs/ckeditor5/latest/framework/guides/support/error-codes.html#error-ckeditor-duplicated-modules
CKEditorError: ckeditor-duplicated-modules
Read more: https://ckeditor.com/docs/ckeditor5/latest/framework/guides/support/error-codes.html#error-ckeditor-duplicated-modules
    at Object.<anonymous> (ckeditor.js:5)
    at Object.push.+z1p (ckeditor.js:5)
    at n (ckeditor.js:5)
    at Module.<anonymous> (ckeditor.js:5)
    at n (ckeditor.js:5)
    at push.+z1p (ckeditor.js:5)
    at ckeditor.js:5
    at ckeditor.js:5
    at Object.+z1p (ckeditor.js:5)
    at __webpack_require__ (bootstrap:84)
    at resolvePromise (zone-evergreen.js:798)
    at resolvePromise (zone-evergreen.js:750)
    at zone-evergreen.js:860
    at ZoneDelegate.invokeTask (zone-evergreen.js:399)
    at Object.onInvokeTask (core.js:28289)
    at ZoneDelegate.invokeTask (zone-evergreen.js:398)
    at Zone.runTask (zone-evergreen.js:167)
    at drainMicroTaskQueue (zone-evergreen.js:569)

@siconghe-gep
Copy link

@ma2ciek

I followed @ecolara3 instruction and hit a brick wall.

the issue is that the custom build tool for ckeditor 5 (https://ckeditor.com/ckeditor-5/online-builder/) results in an ES6 build.

according to: #20 this ES6 build is using some uglifier resulted in throwing compilation error root is undefined for angular projects.

Please add ES5 build option to the custom build tool.

it's already a huge among of pain to customize ckeditor 5 for angular, please do not make it even worse.

@Reinmar Reinmar added resolution:resolved This issue was already resolved (e.g. by another ticket). and removed resolution:solved labels Jul 29, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
resolution:resolved This issue was already resolved (e.g. by another ticket). type:question
Projects
None yet
Development

No branches or pull requests

8 participants