Reputation: 91
I'm stuck with following problem while creating my Flask based blog.
Firstly, I used CKeditor 4 but than upgraded to 5 version.
I can't understand how to handle image upload on server side now, with adapters etc. As for 4 version, I used flask-ckeditor extension and Flask documentation to handle image uploading.
I didn't find any examples for this combination. I understand that I lack knowledge and I'm looking for advice in which direction may I advance and which concepts should I know to approach such subject.
Thanks in advance.
My takes on this so far:
According to https://ckeditor.com/docs/ckeditor5/latest/features/image-upload/simple-upload-adapter.html
(official guide on simplest adapters).
config.simpleUpload.uploadUrl
should be like /upload
route that was used in cke4. Object with URL property needed by cke5 is cke4's upload_successful
which was returned by /upload route.
Upvotes: 0
Views: 1677
Reputation: 91
So I figured it out.
As for cke 4:
/upload
route handled uploading process by returning upload_successful()
from flask-ckeditor extension.
upload_successful()
itself is a jsonify-ing function, which in turn modify arguments to fit json format.
As for cke 5: There were some things aside upload handling, which caused problems.
Plugin used: "Simple upload adapter"
I integrated cke5 by downloading from Online-builder and then reinstalling and rebuilding it by myself. (for this on Ubuntu 20.04 I installed nodejs
and npm
by sudo apt install
.) Plugin is installed by executing from /static/ckeditor
folder:
npm install
npm install --save @ckeditor/ckeditor5-upload
npm run build
(need to wait here for a little)
Different adapters may conflict and not allow Editor to load, so I removed CKFinder adapter from src/ckeditor.js
in import
and .builtinPlugins
sections, replacing them by import SimpleUploadAdapter from '@ckeditor/ckeditor5-upload/src/adapters/simpleuploadadapter.js';
and SimpleUploadAdapter
correspondingly.
.html
, where CKEditor instance is created. body
here is name of flask_wtf
text-field:
<script>
ClassicEditor
.create( document.querySelector( '#body' ), {
extraPlugins: ['SimpleUploadAdapter'],
simpleUpload: {
uploadUrl: '/upload',
},
mediaEmbed: {previewsInData: true}
} )
.catch( error => {
console.error( error.stack );
} );
</script>
Things to notice:
.create( document.querySelector( '#editor' ), {
plugins: [ Essentials, Paragraph, Bold, Italic, Alignment ],
.create( document.querySelector( '#body' ), {
extraPlugins: ['SimpleUploadAdapter'],
So, plugins
-> extraPlugins
and PluginName
-> 'PluginName'
.
/upload
route itself:@main.route('/files/<path:filename>')
def uploaded_files(filename):
app = current_app._get_current_object()
path = app.config['UPLOADED_PATH']
return send_from_directory(path, filename)
@main.route('/upload', methods=['POST'])
def upload():
app = current_app._get_current_object()
f = request.files.get('upload')
# Add more validations here
extension = f.filename.split('.')[-1].lower()
if extension not in ['jpg', 'gif', 'png', 'jpeg']:
return upload_fail(message='Image only!')
f.save(os.path.join(app.config['UPLOADED_PATH'], f.filename))
url = url_for('main.uploaded_files', filename=f.filename)
return jsonify(url=url)
I will edit this answer as I advance in this subject.
Upvotes: 4