PHP/Laravel

Laravel(라라벨) : CKeditor 사용하기

제주도 조랑말 2023. 7. 21. 16:47
728x90

6번까지의 실행결과


 

 

 

 


1. https://ckeditor.com/

 

WYSIWYG HTML Editor with Collaborative Rich Text Editing

Rock-solid, Free WYSIWYG Editor with Collaborative Editing, 200+ features, Full Documentation and Support. Trusted by 20k+ companies.

ckeditor.com

 

2. -> Download (npm (x), CDN(x), Package Zip(o))

압축해제

 

3. 프로젝트 -> public 폴더 -> ckeditor(생성) 

ckeditor 안에 압축해제한 모든 파일 을 복붙 (ckeditor.js 확인)

 

4.

web.php 

use App\Http\Controllers\EditorController; //추가
Route::get('/editor', [EditorController::class,'index']);
Route::post('/store', [EditorController::class,'store']);

 

5. artisan make - EditorController

EditorController

class ... {

 public function index(){
        return view('editor');
    }

    public function store(Request $request){
        echo $request->input('editor');
    }
 

}

 

 

6.

editor.blade.php

<form method="post" action={{ url('store') }}>
    <p><textarea name="editor" id="editor"></textarea></p>
    {{ csrf_field() }}
    <input type="submit" name="submit" value="Submit"/>
</form>

<script src={{ asset('ckeditor/ckeditor.js') }}></script>
<script>
    ClassicEditor
            .create( document.querySelector( '#editor' ) )
            .catch( error => {
                console.error( error );
            } );
</script>

밑 <script>태그 
https://ckeditor.com/docs/ckeditor5/latest/installation/getting-started/quick-start.html

 

Quick start - CKEditor 5 Documentation

Learn how to install, integrate and configure CKEditor 5 Builds and how to work with CKEditor 5 Framework, customize it, create your own plugins and custom editors, change the UI or even bring your own UI to the editor. API reference and examples included.

ckeditor.com

 




여기서부터 사진 업로드  ((((((((((해결 못함

 

7. CKeditor Framework - The complete implementation
https://ckeditor.com/docs/ckeditor5/latest/framework/deep-dive/upload-adapter.html

 

Custom upload adapter - CKEditor 5 Documentation

Learn how to install, integrate and configure CKEditor 5 Builds and how to work with CKEditor 5 Framework, customize it, create your own plugins and custom editors, change the UI or even bring your own UI to the editor. API reference and examples included.

ckeditor.com

 

7-1. 실행

$ php artisan storage:link
$ composer require intervention/image

 

https://image.intervention.io/v2/introduction/installation#integration-in-laravel

 

Installation | Intervention Image v2 | intervention.io

Intervention Image provides an easy way to manipulate images with PHP supporting GD Library and Imagick.

image.intervention.io

 

7-2. config > app.php

 

 

config > app.php

 

8. EditorController.php

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Image;

class EditorController extends Controller
{
    //
    public function index(){
        return view('editor');
    }

    public function store(Request $request){
        echo $request->input('editor');
    }
}

 

 

9. editor.blade.php

6번에 있는 <script>태그를 변경 (The complete implementation)

<form method="post" action={{ url('store') }}>
    <p><textarea name="editor" id="editor"></textarea></p>
    {{ csrf_field() }}
    <input type="submit" name="submit" value="Submit"/>
</form>

<script src={{ asset('ckeditor/ckeditor.js') }}></script>
<script>
        class MyUploadAdapter {
        constructor( loader ) {
            // The file loader instance to use during the upload.
            this.loader = loader;
        }
   
        // Starts the upload process.
        upload() {
            return this.loader.file
                .then( file => new Promise( ( resolve, reject ) => {
                    this._initRequest();
                    this._initListeners( resolve, reject, file );
                    this._sendRequest( file );
                } ) );
        }
   
        // Aborts the upload process.
        abort() {
            if ( this.xhr ) {
                this.xhr.abort();
            }
        }
   
        // Initializes the XMLHttpRequest object using the URL passed to the constructor.
        _initRequest() {
            const xhr = this.xhr = new XMLHttpRequest();
       
            // Note that your request may look different. It is up to you and your editor
            // integration to choose the right communication channel. This example uses
            // a POST request with JSON as a data structure but your configuration
            // could be different.
            xhr.open( 'POST', 'http://example.com/image/upload/path', true );
            xhr.responseType = 'json';
        }
   
        // Initializes XMLHttpRequest listeners.
        _initListeners( resolve, reject, file ) {
            const xhr = this.xhr;
            const loader = this.loader;
            const genericErrorText = `Couldn't upload file: ${ file.name }.`;
       
            xhr.addEventListener( 'error', () => reject( genericErrorText ) );
            xhr.addEventListener( 'abort', () => reject() );
            xhr.addEventListener( 'load', () => {
                const response = xhr.response;
           
                // This example assumes the XHR server's "response" object will come with
                // an "error" which has its own "message" that can be passed to reject()
                // in the upload promise.
                //
                // Your integration may handle upload errors in a different way so make sure
                // it is done properly. The reject() function must be called when the upload fails.
                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.
                // This URL will be used to display the image in the content. Learn more in the
                // UploadAdapter#upload documentation.
                resolve( {
                    default: response.url
                } );
            } );
       
            // Upload progress when it is supported. The file loader has the #uploadTotal and #uploaded
            // properties which are used e.g. to display the upload progress bar in the editor
            // user interface.
            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( file ) {
            // Prepare the form data.
            const data = new FormData();
       
            data.append( 'upload', file );
       
            // Important note: This is the right place to implement security mechanisms
            // like authentication and CSRF protection. For instance, you can use
            // XMLHttpRequest.setRequestHeader() to set the request headers containing
            // the CSRF token generated earlier by your application.
       
            // Send the request.
            this.xhr.send( data );
        }
    }
   
    function MyCustomUploadAdapterPlugin( editor ) {
        editor.plugins.get( 'FileRepository' ).createUploadAdapter = ( loader ) => {
            // Configure the URL to the upload script in your back-end here!
            return new MyUploadAdapter( loader );
        };
    }
   
    ClassicEditor
        .create( document.querySelector( '#editor' ), {
            extraPlugins: [ MyCustomUploadAdapterPlugin ],
       
            // More configuration options.
            // ...
        } )
        .catch( error => {
            console.log( error );
        } );
   
</script>

 

10.

728x90