You are on page 1of 31

Flask-CKEditor Documentation

Release 0.2.0

Grey Li

Feb 21, 2019


Contents

1 Contents 3
1.1 Basic Usage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.2 Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.3 Advanced Usage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
1.4 FAQ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
1.5 Try Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

2 API Reference 13
2.1 API Reference . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

3 Changelog 15
3.1 Changelog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

4 Development 19

5 Authors 21

6 License 23

Python Module Index 25

i
ii
Flask-CKEditor Documentation, Release 0.2.0

CKEditor integration for Flask, add support to image upload, code syntax highlight and more.

Contents 1
Flask-CKEditor Documentation, Release 0.2.0

2 Contents
CHAPTER 1

Contents

1.1 Basic Usage

1.1.1 Installation

$ pip install flask-ckeditor

1.1.2 Initialization

This extension needs to be initialized in the usual way before it can be used:

from flask_ckeditor import CKEditor

app = Flask(__name__)
ckeditor = CKEditor(app)

This extension also supports the Flask application factory pattern by allowing you to create a CKEditor object and
then separately initialize it for an app:

from flask_ckeditor import CKEditor

ckeditor = CKEditor()

def create_app():
app = Flask(__name__)
...
ckeditor.init_app(app)
...
return app

3
Flask-CKEditor Documentation, Release 0.2.0

1.1.3 Include CKEditor Resources

In the template which you want to put a CKEditor textarea, call ckeditor.load() in <head></head> or before
</body>:

<body>
...
{{ ckeditor.load() }}
</body>

In default, it will load the CKEditor resources from CND (cdn.ckeditor.com), you can set
CKEDITOR_SERVE_LOCAL to True to use built-in resources. You can use custom_url to load your cus-
tom CKEditor build:

{{ ckeditor.load(custom_url=url_for('static', filename='ckeditor/ckeditor.js')) }}

CKEditor provide three type of preset (i.e. basic, standard and full), this method default to load standard.
You can use pkg_type parameter or CKEDITOR_PKG_TYPE configuration variable to set the package type. For
example:

{{ ckeditor.load(pkg_type="basic") }}

Or:

app = Flask(__name__)
app.config['CKEDITOR_PKG_TYPE'] = 'basic'
ckeditor = CKEditor(app)

This method is just a helper to generate <script> to include CKEditor resources, you can also write <script>
element directly:

<script src="https://cdn.ckeditor.com/4.10.0/standard/ckeditor.js"></script>

1.1.4 Create A CKEditor textarea

It’s quite simple, just call ckeditor.create() in the template:

<form method="post">
{{ ckeditor.create() }}
<input type="submit">
</form>

1.1.5 Get the Data

Since the CKEditor textarea is just a normal <textarea> element, so you can get the data from request.form
by passing ckeditor as key:

from flask import request, render_template

@app.route('/write')
def new_post():
if request.method == 'POST':
data = request.form.get('ckeditor') # <--
(continues on next page)

4 Chapter 1. Contents
Flask-CKEditor Documentation, Release 0.2.0

(continued from previous page)

return render_template('index.html')

1.1.6 Working with Flask-WTF/WTForms

When using Flask-WTF/WTForms, you can import the CKEditorField provided by Flask-CKEditor and use it
just like StringField:

from flask_wtf import FlaskForm


from flask_ckeditor import CKEditorField
from wtforms import StringField, SubmitField

class PostForm(FlaskForm):
title = StringField('Title')
body = CKEditorField('Body') # <--
submit = SubmitField('Submit')

One more step is to call ckeditor.config() and pass the CKEditorField attribute’s name:

<form method="post">
{{ form.title() }}
{{ form.body() }}
{{ form.submit() }}
</form>

{{ ckeditor.load() }}
{{ ckeditor.config(name='body') }}
</body>

In the view function, you can get the data either by request.form.get('body') or form.body.data.

Tip: Check the demo application at examples/basic and examples/without-flask-wtf.

1.2 Configuration

1.2.1 Register Configuration

Except CKEDITOR_SERVE_LOCAL and CKEDITOR_PKG_TYPE, when you use other configuration variable, you
have to call ckeditor.config() in template to make them register with CKEditor:

<body>
... <!-- {{ ckeditor.load() }} or <script src="/path/to/ckeditor.js"> -->
{{ ckeditor.config() }}
</body>

Note: When using Flask-WTF/WTForms, you have to pass the field name as name in ckeditor.config(),
for example ckeditor.config(name='description'). If you create the CKEditor through ckeditor.
create(), the default value (ckeditor) will be used.

1.2. Configuration 5
Flask-CKEditor Documentation, Release 0.2.0

1.2.2 Available Configuration

The configuration options available were listed below:

Name Default Info


Value
CKEDI- FalseFlag used to set serve resources from local when use ckeditor.
TOR_SERVE_LOCAL load(), default to retrieve from CDN.
CKEDI- 'standard' The package type of CKEditor, one of basic, standard and full.
TOR_PKG_TYPE
CKEDI- None The lang code string to set UI language in ISO 639 format, for example:
TOR_LANGUAGE zh, en, jp etc. Leave it unset to enable auto detection by user’s browser
setting.
CKEDI- CKEditor The height of CKEditor textarea, in pixel.
TOR_HEIGHT default
CKEDI- CKEditor The width of CKEditor textarea, in pixel.
TOR_WIDTH default
CKEDI- None The URL or endpoint that handle file upload.
TOR_FILE_UPLOADER
CKEDI- None The URL or endpoint that handle file browser.
TOR_FILE_BROWSER
CKEDI- False Flag used to enable codesnippet plugin, the plugin must be installed (in-
TOR_ENABLE_CODESNIPPET cluded in built-in resources).
CKEDI- Set code snippet highlight theme when codesnippet plugin was enabled.
'monokai_sublime'
TOR_CODE_THEME
CKEDI- [] A list of extra plugins used in CKEditor, the plugins must be installed.
TOR_EXTRA_PLUGINS
CKEDI- False Flag used to enable CSRF protect for image uploading, see Advanced Us-
TOR_ENABLE_CSRF age for more details.
CKEDI- 'Upload Default error message for failed upload.
TOR_UPLOAD_ERROR_MESSAGE
failed.'

1.2.3 Custom Configuration String

In addition, you can pass custom settings with custom_config argument:

{{ ckeditor.config(custom_config="uiColor: '#9AB8F3'") }}

Keep it mind that the proper syntax for each option is configuration name : configuration value.
You can use comma to separate multiple key-value pairs. See the list of available configuration settings on CKEditor
documentation.

1.2.4 Configuring Multiple Text Area

If you need create multiple text area in one page, here are some tips:

Without Flask-WTF/WTForms

Create two text area with different name and configure it with the name:

6 Chapter 1. Contents
Flask-CKEditor Documentation, Release 0.2.0

<h1>About me</h1>
{{ ckeditor.create(name='bio') }}

<h1>About my team</h1>
{{ ckeditor.create(name='team') }}

{{ ckeditor.load() }}

{{ ckeditor.config(name='bio') }}
{{ ckeditor.config(name='team') }}

With Flask-WTF/WTForms

When create multiple form with Flask-WTF/WTForms, you just need to create multiple CKEditorField field:

from flask_wtf import FlaskForm


from flask_ckeditor import CKEditorField
from wtforms import StringField, SubmitField

class PostForm(FlaskForm):
title = StringField('Title')
bio = CKEditorField('About me') # <--
team = CKEditorField('About my team') # <--
submit = SubmitField('Submit')

In the template, you render them and configure them with the right name:

{{ form.bio() }}
{{ form.team() }}
{{ form.submit() }}

{{ ckeditor.load() }}

{{ ckeditor.config(name='bio') }}
{{ ckeditor.config(name='team') }}

1.2.5 Overwriting Global Configurations

Sometimes you may want to use different configuration for multiple text area, in this case, you can pass the specific
keyword arguments into ckeditor.config() directly.
The keyword arguments should mapping the corresponding configration variable in this way:
• CKEDITOR_LANGUAGE –> language
• CKEDITOR_WIDTH –> width
• CKEDITOR_FILE_UPLOADER –> file_uploader
• etc
example:

{{ ckeditor.config(lanuage='en', width=500) }}

1.2. Configuration 7
Flask-CKEditor Documentation, Release 0.2.0

In the end, the keyword argument you pass will overwrite the corresponding configurations.
Comparatively, you can use serve_local and pkg_type in ckeditor.load() to overwrite
CKEDITOR_SERVE_LOCAL and CKEDITOR_PKG_TYPE.

1.3 Advanced Usage

1.3.1 Image Upload

CKEditor >= 4.5

The bulit-in CKEditor package include a File Browser plugin. With this plugin, you can upload and insert image with
image widget. You need set CKEDITOR_FILE_UPLOADER to the URL or endpoint which handle upload files, and
the upload view must return upload_success() call with the uploaded image’s url. Usually, you also need to
validate uploaded image, then you can use upload_fail() to return an error message with message argument.
If message was None, the value in configuration variable CKEDITOR_UPLOAD_ERROR_MESSAGE will be used,
default to Upload failed.. Here is the full example:

from flask_ckeditor import upload_success, upload_fail

app.config['CKEDITOR_FILE_UPLOADER'] = 'upload' # this value can be endpoint or url

@app.route('/files/<path:filename>')
def uploaded_files(filename):
path = '/the/uploaded/directory'
return send_from_directory(path, filename)

@app.route('/upload', methods=['POST'])
def upload():
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('/the/uploaded/directory', f.filename))
url = url_for('uploaded_files', filename=f.filename)
return upload_success(url=url) # return upload_success call

Note: The key pass to request.files.get() must be 'upload',

it’s defined by CKEditor and it’s not the name of the view function.
In the template, you have to call ckeditor.config() to make configuration work:

{{ ckeditor.config() }}

Tip: When using Flask-WTF/WTForms, you have to pass the field name as name in ckeditor.config(),
for example ckeditor.config(name='description'). If you create the CKEditor through ckeditor.
create(), the default value (ckeditor) will be used.

Now you will find the Upload tab appear in image widget. Besides, you can drag and drop image directly into the
editor area or copy and paste the image (CKEditor >= 4.5).

8 Chapter 1. Contents
Flask-CKEditor Documentation, Release 0.2.0

Tip: Check the demo application at examples/image-upload/.

CKEditor < 4.5

If the CKEditor version you use was under 4.5, you will need to use @ckeditor.uploader to decorated the view
function that handle the file upload. The upload view must return the uploaded image’s url. For example:

from flask import send_from_directory

app.config['CKEDITOR_FILE_UPLOADER'] = 'upload' # this value can be endpoint or url

@app.route('/files/<filename>')
def uploaded_files(filename):
path = '/the/uploaded/directory'
return send_from_directory(path, filename)

@app.route('/upload', methods=['POST'])
@ckeditor.uploader
def upload():
f = request.files.get('upload')
f.save(os.path.join('/the/uploaded/directory', f.filename))
url = url_for('uploaded_files', filename=f.filename)
return url

You can use configuration variable CKEDITOR_UPLOAD_ERROR_MESSAGE to customize the error message when
upload failed, default to Upload failed.

Note: The key pass to request.files.get() must be 'upload',

it’s defined by CKEditor and it’s not the name of the view function.
In the template, you have to call ckeditor.config() to make configuration work:

{{ ckeditor.config() }}

Tip: When using Flask-WTF/WTForms, you have to pass the field name as name in ckeditor.config(),
for example ckeditor.config(name='description'). If you create the CKEditor through ckeditor.
create(), the default value (ckeditor) will be used.

Now you will find the Upload tab appear in image widget.

1.3.2 CSRF Protect for Image Upload

Required version: CKEditor >= 4.9.0


The CSRF Protect feature was provided by Flask-WTF’s CSRFProtect extension, so you have to install Flask-WTF
first:

$ pip install flask-wtf

Then initialize the CSRFProtect extension:

1.3. Advanced Usage 9


Flask-CKEditor Documentation, Release 0.2.0

from flask_wtf.csrf import CSRFProtect

app = Flask(__name__)

# the secret key used to generate CSRF token


app.config['SECRET_KEY'] = 'dev key'

# enable CSRF protection


app.config['CKEDITOR_ENABLE_CSRF'] = True

csrf = CSRFProtect(app)

Make sure to set the secret key and set CKEDITOR_ENABLE_CSRF to True. Now all the image upload request will
be protected!

1.3.3 Code Snippet Highlight

The bulit-in CKEditor package include a Code Snippet plugin. You need to set
CKEDITOR_ENABLE_CODESNIPPET to True to enable it. You can set the code theme through configura-
tion option CKEDITOR_CODE_THEME. The default theme was monokai_sublime. See all available themes and
the list of valid theme string on this page.
Another step was load code theme resources in the page you want to display the text:

<head>
...
{{ ckeditor.load_code_theme() }}
</head>

Check the demo application at examples/codesnippet/.

1.4 FAQ

1.4.1 How to make this extension work with Flask-Admin?

Ckeck this SO answer and the demo application at examples/flask-admin.

1.5 Try Examples

Open a terminal, type the commands below one by one:

$ git clone https://github.com/greyli/flask-ckeditor


$ cd flask-ckeditor/examples
$ pip install -r requirements.txt
$ python basic/app.py

Then go to http://127.0.0.1:5000 with your favourite browser.


Aside from the basic example, there are four additional examples:
• examples/image-upload: This example demonstrate how to support image upload in Flaks-CKEditor.
• examples/codesnippet: This example demonstrate how to use Code Snippet plugin.

10 Chapter 1. Contents
Flask-CKEditor Documentation, Release 0.2.0

• examples/without-flask-wtf: This example demonstrate how to use CKEditor without Flask-WTF.


• examples/flask-admin: This example demonstrate how to use CKEditor for Flask-Admin.

1.5. Try Examples 11


Flask-CKEditor Documentation, Release 0.2.0

12 Chapter 1. Contents
CHAPTER 2

API Reference

If you are looking for information on a specific function, class or method, this part of the documentation is for you.

2.1 API Reference

2.1.1 CKEditor Object in Template

2.1.2 CKEditor Object in Python

2.1.3 Image Upload

2.1.4 Utils

13
Flask-CKEditor Documentation, Release 0.2.0

14 Chapter 2. API Reference


CHAPTER 3

Changelog

3.1 Changelog

3.1.1 0.4.3

Release date: 2018/11/8


• Add CSRF protect support for image uplaoding, based on Flask-WTF (CSRFProtect).

3.1.2 0.4.2

Release date: 2018/8/24


• Add documentation.
• Remove built-in support for markdown plugin since it’s unmaintained and not work with CKEditor > 4.6.
• Rename argument codesnippet to enable_codesnippet in ckeditor.config().
• Add serve_local argument for ckeditor.load().

3.1.3 0.4.1

Release date: 2018/6/8


• Change built-in resource’s url path to ckeditor/static/... to prevent conflict with user’s static path.

3.1.4 0.4.0

Release date: 2018/5/29


• Add basic unit test.

15
Flask-CKEditor Documentation, Release 0.2.0

• Update resources, fix plugin register bug, use CKEditor 4.9.2.


• Add configuration parameter CKEDITOR_ENABLE_CODESNIPPET, used to enable/disable Code Snippet
plugin.
• Added Markdown plugin into built-in resouce, enabled markdown mode via
CKEDITOR_ENABLE_MARKDOWN.
• Added configuration parameter CKEDITOR_EXTRA_PLUGINS, a list used to register extra plugins.

3.1.5 0.3.3

Release date: 2018/2/4


• Added support to set name and value when using ckeditor.create().

3.1.6 0.3.2

Release date: 2018/1/15


• Fixed built-in resources bug.

3.1.7 0.3.1

Release date: 2018/1/13


• The value of CKEDITOR_FILE_UPLOADER, CKEDITOR_FILE_BROWSER, file_uploader and
file_browser in ckeditor.config() can be URL or endpoint.
• Change CKEDITOR_FILE_UPLOAD_URL to CKEDITOR_FILE_UPLOADER.
• Change CKEDITOR_FILE_BROWSER_URL to CKEDITOR_FILE_BROWSER.
• Change ckeditor.config(file_upload_url) to ckeditor.config(file_uploader).
• Change ckeditor.config(file_browser_url) to ckeditor.config(file_browser).

3.1.8 0.3

Release date: 2017/12/4


• Set custom resource url with custom_url argument in load().
• Added support for configuration, config() method used to load config.
• Added support to upload image.
• Added local resources, it can be enabled with CKEDITOR_SERVE_LOCAL, default to False.

3.1.9 0.2

Release date: 2017/9/29


• Added example and basic documentation.
• Added support to custom version and pakage type.
• Import CKEditorField directly from flask_ckeditor.

16 Chapter 3. Changelog
Flask-CKEditor Documentation, Release 0.2.0

• Change include_ckeditor() to load().

3.1.10 0.1

Initialize release.

3.1. Changelog 17
Flask-CKEditor Documentation, Release 0.2.0

18 Chapter 3. Changelog
CHAPTER 4

Development

We welcome all kinds of contributions. You can run test like this:

$ python setup.py test

19
Flask-CKEditor Documentation, Release 0.2.0

20 Chapter 4. Development
CHAPTER 5

Authors

Maintainer: Grey Li
See also the list of contributors who participated in this project.

21
Flask-CKEditor Documentation, Release 0.2.0

22 Chapter 5. Authors
CHAPTER 6

License

This project is licensed under the MIT License (see the LICENSE file for details).

23
Flask-CKEditor Documentation, Release 0.2.0

24 Chapter 6. License
Python Module Index

f
flask_ckeditor, 13
flask_ckeditor.utils, 13

25
Flask-CKEditor Documentation, Release 0.2.0

26 Python Module Index


Index

F
flask_ckeditor (module), 13
flask_ckeditor.utils (module), 13

27

You might also like