Closed bekab95 closed 6 years ago
Here are some basic examples. However, image upload behavior changed since CKEditor 4.5, I will release a new version to support it today.
I need it to use with flask admin, upload image or better is to browse directory too and if you can help me that would be great
I just updated the newer example for image upload and release 0.4.0.
@greyli where are you telling ckeditor to override image field ? I need it to use with flask-admin and maybe it has to be without WTF..
I don't understand your question. What's the image field?
When you set CKEDITOR_FILE_UPOLOADER
with proper value, you can just drag and drop the image file into the editor or upload with image widget.
These resources may be helpful:
@greyli Are you planning adding directory browser ? I think it is CKfinder
I did think about it, but currently, I don't have time to investigate and implement it. Happy to accept PR addressing this.
Can I use it without FlaskForm class ?
Sure, check out this example.
In Flask Admin Standard way is to override StringField but for your extension I can not understand for images how to get worked it..
flask_ckeditor.CKEditorField
CKEDITOR_FILE_UPLOADER
to the upload handler view's endpointSo.. tried several things and not working, may Flask-Admin needs different details to upload images within ckeditor
Provide the error traceback and a minimal application will be helpful.
class CKTextAreaWidget(widgets.TextArea):
def __call__(self, field, **kwargs):
# add WYSIWYG class to existing classes
existing_classes = kwargs.pop('class', '') or kwargs.pop('class_', '')
kwargs['class'] = u'%s %s' % (existing_classes, "ckeditor")
return super(CKTextAreaWidget, self).__call__(field, **kwargs)
class CKTextAreaField(TextAreaField):
widget = CKTextAreaWidget()
class OffersView(ModelView):
column_list = ["title_ka", "title_en", "title_ru", "is_main", "is_enabled", "position"]
form_overrides = dict(desc_ka=CKTextAreaField,desc_en=CKTextAreaField,desc_ru=CKTextAreaField)
create_template = 'edit.html'
edit_template = 'edit.html'
def is_accessible(self):
if flask_login.current_user.is_authenticated:
user = CustomUser.objects.get(email=flask_login.current_user.id)
return user.is_superuser
def inaccessible_callback(self, name, **kwargs):
# redirect to login page if user doesn't have access
return redirect(url_for('login', next=request.url))
{% extends 'admin/model/edit.html' %}
{% block tail %}
{{ super() }}
<script src="//cdn.ckeditor.com/4.9.2/full/ckeditor.js"></script>
<script type="text/javascript">
$('.control-group a').click( function(e) {e.preventDefault();
for(var instanceName in CKEDITOR.instances)
CKEDITOR.remove(CKEDITOR.instances[instanceName]);
CKEDITOR.replaceAll('ckeditor');
return false; } );
</script>
{% endblock %}
form override does not work for your extension, you may test it for flask-admin
I never used Flask-Admin before, so I can't help you too much. IMO, you should replace your code like this:
from flask_ckeditor import CKEditorField
class OffersView(ModelView):
column_list = ["title_ka", "title_en", "title_ru", "is_main", "is_enabled", "position"]
form_overrides = dict(desc_ka=CKEditorField, desc_en=CKEditorField, desc_ru=CKEditorField)
create_template = 'edit.html'
edit_template = 'edit.html'
def is_accessible(self):
if flask_login.current_user.is_authenticated:
user = CustomUser.objects.get(email=flask_login.current_user.id)
return user.is_superuser
def inaccessible_callback(self, name, **kwargs):
# redirect to login page if user doesn't have access
return redirect(url_for('login', next=request.url))
You should provide the error traceback or I can't know what's the actual problem. Besides, Expected behavior and Actual behavior also helpful.
I will see further in future thanks.
https://stackoverflow.com/questions/50675748/can-not-catch-ckeditor-id-and-reload-instance-on-it
this is other issue if you can help me ?
So, I have done some tests with flask admin and I got upload option but when I am attempting to upload image it has 404 error (there is extra parameters in form action='/upload?some_params_of_ckeditor may this is the issue ? )
As I have seen it needs csrf token or I am doing something wrong with flask admin
SO I avoid csrf but now I am getting {"filename":"","uploaded":1,"url":"/files/GeoAdsCover_1.png"} this response when uploading image in ckeditor, so it is not parsing name
4.9.2 it is working on this version, I will test fully for flask admin and bring you full example :)
from flask_ckeditor import *
csrf = CSRFProtect(app)
csrf.init_app(app)
ckeditor = CKEditor(app)
app.config['CKEDITOR_SERVE_LOCAL'] = False
app.config['CKEDITOR_HEIGHT'] = 400
app.config['CKEDITOR_FILE_UPLOADER'] = 'upload'
app.config['UPLOADED_PATH'] = os.path.join(basedir, 'uploads')
@app.route('/files/<filename>')
@csrf.exempt
def uploaded_files(filename):
path = app.config['UPLOADED_PATH']
return send_from_directory(path, filename)
import uuid
@app.route('/upload', methods=['POST'])
@csrf.exempt
def upload():
f = request.files.get('upload')
extension = f.filename.split('.')[1].lower()
if extension not in ['jpg', 'gif', 'png', 'jpeg']:
return upload_fail(message='Image only!')
unique_filename = str(uuid.uuid4())
f.filename = unique_filename + '.' + extension
f.save(os.path.join(app.config['UPLOADED_PATH'], f.filename))
url = url_for('uploaded_files', filename=f.filename)
return upload_success(url=url)
in flask admin edit.html
CKEDITOR.plugins.addExternal( 'filebrowser', '/static/ckeditor/filebrowser/', 'plugin.js' );
CKEDITOR.config.extraPlugins = 'filebrowser';
CKEDITOR.config.filebrowserBrowseUrl = '/upload';
If I will use {{ ckeditor.load() }} it will load CKEDITOR but it will not add plugin to ckeditor window and that is a issue left
app.config['CKEDITOR_FILE_UPLOADER'] = 'upload'
does not have any impact
How do you create the textarea? Did you call {{ ckeditor.config() }}
in the template?
@greyli Yes I have Called But did not work, I will test it again with some details and tell you
Currently, I do not know too much about Flask-Admin, I will try to learn how to integrate Flask-Admin with Flask-CKEditor when I have free time.
@greyli integration is not problem, I have to add additional JS to get work image uploads
CKEDITOR.plugins.addExternal( 'filebrowser', '/static/ckeditor/filebrowser/', 'plugin.js' ); CKEDITOR.config.extraPlugins = 'filebrowser'; CKEDITOR.config.filebrowserBrowseUrl = '/upload';
When calling {{ ckeditor.config() }}
, Flask-CKEditor initialize a CKEditor for a <textarea>
named ckeditor
. You may need to find out what is the name used when Flask-Admin create the <textarea>
, and pass it to config()
(e.g. {{ ckeditor.config(name='the_name_attr') }}
).
@greyli that is not a problem. ckeditor is working, only image upload window is not working without adding extra plugin, I will test it again.
In addition can you write documentation about adding extra plugins ? for example adding responsive table plugin.
I confirm without this
<script>
CKEDITOR.config.filebrowserUploadUrl = '/upload';
</script>
Image Upload is not showing up in ckeditor in flask admin
The filebrowserUploadUrl
config will be added after calling ckedtior.config()
(flask_ckeditor/init.py#L101), so it's important to pass correct name attribute.
You can pass extra plugins name as a list in CKEDITOR_EXTRA_PLUGINS
, such as ['responsive_table']
, it also needs to call ckedtior.config()
to make it work.
Show me ckedtior.config() example please
name=body is that for to load ckeditor on body ? I need to know how to tell ckeditor cobfig that image upload url is /upload
ckeditor.config()
is the way to tell CKEditor what is the upload URL. The name should be the name
value of CKEditor <textarea>
, you need to render the page, click F12 and find the textarea element, then you will get the correct name value.
it is not required for me to tell which is the textarea ckeditor already loads without telling that. i need to tell config that to use url for upload.
You set app.config['CKEDITOR_FILE_UPLOADER'] = 'upload'
, then Flask-CKEditor will turn it into url, and when you call ckeditor.config()
, it will generate JavaScript code to set the url (i.e. filebrowserUploadUrl: "/upload"
).
So I only was loading ckeditor without
ckeditor.config()
and do I have to call ckeditor.config()
too ??
If you want to write config code yourself, for example:
CKEDITOR.plugins.addExternal( 'filebrowser', '/static/ckeditor/filebrowser/', 'plugin.js' );
CKEDITOR.config.extraPlugins = 'filebrowser';
CKEDITOR.config.filebrowserBrowseUrl = '/upload';
then you can skip cdeditor.config()
only calling cdeditor.config()
is not working
app.config['CKEDITOR_FILE_UPLOADER'] = 'upload'
does not have any impact that is problem
https://github.com/zrq495/flask-ckfinder Can you also fork this ?
As I said, you need to find out the name of CKEditor <textarea>
and pass it as cdeditor.config(name='the_name')
.
I'll try to integrate a file browser when I have free time.
@greyli So
cdeditor.config(name='the_name') does not needed, ckeditor is loading without it, but app.config['CKEDITOR_FILE_UPLOADER'] = 'upload' this does not work when pressing image icon in ckeditor, it is not loading upload tab
to load upload tag it needs
CKEDITOR.plugins.addExternal( 'filebrowser', '/static/ckeditor/filebrowser/', 'plugin.js' ); CKEDITOR.config.extraPlugins = 'filebrowser'; CKEDITOR.config.filebrowserBrowseUrl = '/upload';
and how to tell ckeditor upload url without extra JS above ?
If you want to tell CKEditor the upload URL without extra JS, set this in Python:
app.config['CKEDITOR_FILE_UPLOADER'] = 'upload'
And call it in Jinja:
ckeditor.config(name='the_name')
So that I was talking about that this:
app.config['CKEDITOR_FILE_UPLOADER'] = 'upload'
is not working without extra JS
that is bug
Do you notice the "And" in my last comment? As I said, ckeditor.config(name='the_name')
will generate the JS code, so you have to call it to make the configuration work.
Nope, I have tried that too and other combinations too.. but not working without extra JS
You have to pass the correct name value.
I am using Flask-Admin and have already integrated ckeditor and works with only texts but I need to upload images with text too and I need more examples if it is possible
Without WTF