This article shows how to integrate Tinymce 5 with Flask even including csrf protection!
Text area
<textarea id="content"></textarea>
Tinymce
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/tinymce/5.10.2/tinymce.min.js"></script>
<script type="text/javascript">
tinymce.init({
selector: '#content',
plugins: [
'advlist autolink link image imagetools lists charmap print preview hr anchor pagebreak spellchecker',
'searchreplace wordcount visualblocks visualchars code fullscreen insertdatetime media nonbreaking',
'save table contextmenu directionality template paste textcolor codesample'
],
imagetools_toolbar: "rotateleft rotateright | flipv fliph | editimage imageoptions",
toolbar: 'insertfile undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image | print preview media fullpage | forecolor backcolor emoticons | codesample',
relative_urls: false,
images_upload_handler : function(blobInfo, success, failure) {
var xhr, formData;
xhr = new XMLHttpRequest();
xhr.withCredentials = false;
xhr.open('POST', '{{ url_for('upload_function_name_here') }}'); // change this
xhr.onload = function() {
var json;
if (xhr.status != 200) {
failure('HTTP Error: ' + xhr.status);
return;
}
json = JSON.parse(xhr.responseText);
// if (!json || typeof json.file_path != 'string') {
// failure('Invalid JSON: ' + xhr.responseText);
// return;
// }
success(json.location);
};
formData = new FormData();
formData.append('file', blobInfo.blob(), blobInfo.filename());
formData.append('csrf_token', '{{csrf_token()}}'); // i add csrf_token
xhr.send(formData);
},
image_title: true,
automatic_uploads: true,
images_reuse_filename: false,
images_upload_base_path: '/static/gallery/', // i serve from /static/gallery and save to /static/gallery
codesample_languages: [
{ text: 'HTML/XML', value: 'markup' },
{ text: 'JavaScript', value: 'javascript' },
{ text: 'CSS', value: 'css' },
{ text: 'Processing', value: 'processing' },
{ text: 'Python', value: 'python' }
],
width: "100%",
});
</script>
First add to config GALLERY_UPLOAD_PATH with value the absolute path of your static folder
flask
from flask import abort
from flask import current_app
from flask import Response
from flask import request
from flask import url_for
from flask import jsonify
from werkzeug.utils import secure_filename
@module_blueprint.route('/file-upload', methods=['GET', 'POST'])
def file_upload():
"""
Upload post images from tinyMce editor.
Save image to path.
returns: json { location: path }
"""
# Get the file user has uploaded inside the tinymce editor.
uploaded_file = request.files.get('file')
if uploaded_file:
filename = secure_filename(uploaded_file.filename).lower()
# Validate the contents of the file. Check the header of the file is infact an image.
# valid_img_ext = validate_img(uploaded_file.stream)
# Split filename and extension, rename & add correct extension.
# filename = secure_filename(os.path.splitext(filename)[0] + valid_img_ext)
img_path = os.path.join(current_app.config['GALLERY_UPLOAD_PATH'], filename)
# Check if user directory exists, create if nessecary.
if not os.path.exists(current_app.config['GALLERY_UPLOAD_PATH']):
try:
os.makedirs(current_app.config['GALLERY_UPLOAD_PATH'])
except OSError as e:
if e.errno != errno.EEXIST:
raise
# Save the image.
uploaded_file.save(img_path)
location = url_for('static', filename='gallery/' + filename)
print(location)
# Return image path back to editor
return jsonify({'location': location})
abort(Response('404 - Image failed to upload'))
Flask 2.x
Kevin7’s article was not working, adapted it
Written by
Abdur-Rahmaan Janhangeer
Chef
Python author of 7+ years having worked for Python companies around the world
Suggested Posts
How to implement beautiful notifications in Flask
Since you already know how to implement notifications, let’s see how to implement beautiful notifica...
How to implement notification in Flask
Implementing notifications in Flask goes way beyond using flash. You have to add this snippet in you...
How to integrate P5JS with Flask-SocketIO
P5Js is an implementation of processing.org’s library in JavaSript. It can be thought of as a canvas...