web-dev-qa-db-ja.com

CKEditor 5で画像アップロードサポートを有効にする方法

Ckeditor v5をプロジェクトに使用します。画像プラグインを使用しようとしましたが、それに関する十分な情報が見つかりません。

Demoe here が表示されている場合は、ドラッグアンドドロップで画像を簡単にアップロードできます。しかし、ダウンロードバルーンZipで試してみると、画像をドラッグアンドドロップしようとしても何も起こりません。エラーもありません。

Downladableバリアントでこのイメージサポートを使用する方法はありますか?

9
Lukas Gund

はい、利用可能なすべてのビルドに画像のアップロードが含まれています。ただし、それを機能させるには、既存のアップロードアダプターの1つを構成するか、独自のアダプターを作成する必要があります。要するに、アップロードアダプターは単純なクラスであり、その役割は、サーバーにファイルを(必要な方法で)送信し、完了後に返されたプロミスを解決することです。

詳細については、公式の Image upload ガイドを参照するか、以下の利用可能なオプションの短い要約を参照してください。

公式アップロードアダプター

2つの組み込みアダプターがあります。

  • CKFinder の場合、CKFinderコネクタをサーバーにインストールする必要があります。

    サーバーにコネクタをインストールしたら、 config.ckfinder.uploadUrl オプション:

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

    CKFinderのクライアント側ファイルマネージャーとの完全な統合を有効にすることもできます。 CKFinder統合デモ を確認し、詳細を CKFinder統合 ガイドで読んでください。

  • Easy Image サービスの場合 CKEditor Cloud Services の一部です。

    クラウドサービスアカウントをセットアップする が必要で、一度 トークンエンドポイントを作成する それを使用するようにエディターを構成する必要があります。

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

免責事項:これらは独自のサービスです。

カスタムアップロードアダプター

また、サーバーに希望する方法で(またはファイルを送信したい場所に)ファイルを送信する独自​​のアップロードアダプターを作成することもできます。

カスタムイメージアップロードアダプター ガイドを参照して、実装方法を学習してください。

例(つまり、セキュリティが組み込まれていない)アップロードアダプターは次のようになります。

class MyUploadAdapter {
    constructor( loader ) {
        // CKEditor 5's 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 );
    }
}

これは次のように有効にできます:

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 );
    } );

注:上記は単なるアップロードアダプタの例です。そのため、セキュリティメカニズム(CSRF保護など)は組み込まれていません。

17
Reinmar

このコントロールの使用方法に関する情報を探していたところ、公式のドキュメントはかなり最小限でした。しかし、多くの試行錯誤を経て機能するようになったので、共有すると思いました。

最終的に、Angular 8でCKEditor 5のシンプルなアップロードアダプターを使用しましたが、正常に動作します。ただし、アップロードアダプターがインストールされているckeditorのカスタムビルドを作成する必要があります。すでにckeditor Angularファイルがあります。

最初に、新しいangularプロジェクトディレクトリを作成し、「cKEditor-Custom-Build」または何かを呼び出します。ngnew(Angular CLI)を実行せず、代わりにnpmを使用してベースビルドを取得します。この例では、クラシックエディターを使用しています。

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

Githubに移動して、プロジェクトを新しい光沢のあるビルドディレクトリに複製またはダウンロードします。

vSコードを使用している場合は、ディレクトリを開いてターミナルボックスを開き、依存関係を取得します。

npm i

これでベースビルドができたので、アップロードアダプターをインストールする必要があります。 ckEditorには1つあります。このパッケージをインストールして、単純なアップロードアダプターを取得します。

npm install --save @ckeditor/ckeditor5-upload

..これが完了したら、プロジェクトのckeditor.jsファイルを開きます。 「src」ディレクトリにあります。 ckEditorをいじくり回している場合、その内容はおなじみのはずです。

新しいjsファイルをckeditor.jsファイルにインポートします。このファイルにはインポートの全負荷があり、それをすべて下にドロップします。

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

...次に、プラグインの配列にインポートを追加します。クラシックエディターを使用しているため、私のセクションは「ClassicEditor.builtinPlugins」と呼ばれ、TableToolbarの横に追加します。それがすべて設定されました。このため、追加のツールバーや設定は必要ありません。

Ckeditor-custom-buildをビルドします。

npm run build

Angularの魔法がその処理を行い、プロジェクト内に「ビルド」ディレクトリが作成されます。これがカスタムビルド用です。

ここでangularプロジェクトを開いて、新しいビルドのライブ用のディレクトリを作成します。実際には、アセットのサブディレクトリに私のものを配置しますが、参照できる場所であればどこでもかまいません。

「ngClassicEditor」のような名前の「src/assets」内にディレクトリを作成します。名前を問わず、ビルドファイルを(作成したばかりの)ディレクトリにコピーします。次に、エディターを使用するコンポーネントで、新しいビルドへのパスを持つimportステートメントを追加します。

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

ほとんどできた...

最後のビットは、画像をアップロードするためにアダプターが使用する必要があるAPIエンドポイントでアップロードアダプターを構成することです。コンポーネントクラスに設定を作成します。

  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>'
  }
}

};

私は実際に environment transform を使用していますが、これはURIがdevからプロダクションに変わるためですが、必要に応じてそこに直接URLをハードコーディングできます。

最後の部分は、テンプレートでエディターを構成して、新しい構成値を使用することです。 component.htmlを開き、ckeditorエディタータグを変更します。

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

それでおしまい。できました。テスト、テストテスト。

私のAPIは.Net APIであり、サンプルコードが必要な場合は共有できます。これが役立つことを本当に願っています。

1
Darren Street