Python的Flask框架中集成CKeditor富文本编辑器的教程


Posted in Python onJune 13, 2016

CKeditor是目前最优秀的可见即可得网页编辑器之一,它采用JavaScript编写。具备功能强大、配置容易、跨浏览器、支持多种编程语言、开源等特点。它非常流行,互联网上很容易找到相关技术文档,国内许多WEB项目和大型网站均采用了CKeditor。

下载CKeditor
访问CKeditor官方网站,进入下载页面,选择Standard Package(一般情况下功能足够用了),然后点击Download CKEditor按钮下载ZIP格式的安装文件。如果你想尝试更多的功能,可以选择下载Full Package。

下载好CKeditor之后,解压到Flask项目static/ckeditor目录即可。

在Flask项目中使用CKeditor
在Flask项目中使用CKeditor只需要执行两步就可以了:

在<script>标签引入CKeditor主脚本文件。可以引入本地的文件,也可以引用CDN上的文件。
使用CKEDITOR.replace()把现存的<textarea>标签替换成CKEditor。
示例代码:

<!DOCTYPE html>
<html>
  <head>
    <title>A Simple Page with CKEditor</title>
    <!-- 请确保CKEditor文件路径正确 -->
    <script src="{{ url_for('static', filename='ckeditor/ckeditor.js') }}"></script>
  </head>
  <body>
    <form>
      <textarea name="editor1" id="editor1" rows="10" cols="80">
        This is my textarea to be replaced with CKEditor.
      </textarea>
      <script>
        // 用CKEditor替换<textarea id="editor1">
        // 使用默认配置
        CKEDITOR.replace('editor1');
      </script>
    </form>
  </body>
</html>

因为CKeditor足够优秀,所以第二步也可只为<textarea>追加名为ckeditor的class属性值,CKeditor就会自动将其替换。例如:

<!DOCTYPE html>
<html>
  <head>
    <title>A Simple Page with CKEditor</title>
    <!-- 请确保CKEditor文件路径正确 -->
    <script src="{{ url_for('static', filename='ckeditor/ckeditor.js') }}"></script>
  </head>
  <body>
    <form>
      <textarea name="editor1" id="editor1" class="ckeditor" rows="10" cols="80">
        This is my textarea to be replaced with CKEditor.
      </textarea>
    </form>
  </body>
</html>

CKEditor脚本文件也可以引用CDN上的文件,下面给出几个参考链接:

<script src="//cdn.ckeditor.com/4.4.6/basic/ckeditor.js"></script>

 基础版(迷你版)

<script src="//cdn.ckeditor.com/4.4.6/standard/ckeditor.js"></script>

 标准版

<script src="//cdn.ckeditor.com/4.4.6/full/ckeditor.js"></script>

完整版
开启上传功能
默认配置下,CKEditor是没有开启上传功能的,要开启上传功能,也相当的简单,只需要简单修改配置即可。下面来看看几个相关的配置值:

  • filebrowserUploadUrl :文件上传路径。若设置了,则上传按钮会出现在链接、图片、Flash对话窗口。
  • filebrowserImageUploadUrl : 图片上传路径。若不设置,则使用filebrowserUploadUrl值。
  • filebrowserFlashUploadUrl : Flash上传路径。若不设置,则使用filebrowserUploadUrl值。

为了方便,这里我们只设置filebrowserUploadUrl值,其值设为/ckupload/(后面会在Flask中定义这个URL)。

设置配置值主要使用2种方法:

方法1:通过CKEditor根目录的配置文件config.js来设置:

CKEDITOR.editorConfig = function( config ) {
  // ...
  // file upload url
  config.filebrowserUploadUrl = '/ckupload/';
  // ...
};

方法2:将设置值放入作为参数放入CKEDITOR.replace():

<script>
CKEDITOR.replace('editor1', {
  filebrowserUploadUrl: '/ckupload/',
});
</script>

Flask处理上传请求
CKEditor上传功能是统一的接口,即一个接口可以处理图片上传、文件上传、Flash上传。先来看看代码:

def gen_rnd_filename():
  filename_prefix = datetime.datetime.now().strftime('%Y%m%d%H%M%S')
  return '%s%s' % (filename_prefix, str(random.randrange(1000, 10000)))

@app.route('/ckupload/', methods=['POST'])
def ckupload():
  """CKEditor file upload"""
  error = ''
  url = ''
  callback = request.args.get("CKEditorFuncNum")
  if request.method == 'POST' and 'upload' in request.files:
    fileobj = request.files['upload']
    fname, fext = os.path.splitext(fileobj.filename)
    rnd_name = '%s%s' % (gen_rnd_filename(), fext)
    filepath = os.path.join(app.static_folder, 'upload', rnd_name)
    # 检查路径是否存在,不存在则创建
    dirname = os.path.dirname(filepath)
    if not os.path.exists(dirname):
      try:
        os.makedirs(dirname)
      except:
        error = 'ERROR_CREATE_DIR'
    elif not os.access(dirname, os.W_OK):
      error = 'ERROR_DIR_NOT_WRITEABLE'
    if not error:
      fileobj.save(filepath)
      url = url_for('static', filename='%s/%s' % ('upload', rnd_name))
  else:
    error = 'post error'
  res = """

<script type="text/javascript">
 window.parent.CKEDITOR.tools.callFunction(%s, '%s', '%s');
</script>

""" % (callback, url, error)
  response = make_response(res)
  response.headers["Content-Type"] = "text/html"
  return response

上传文件的获取及保存部分比较简单,是标准的文件上传。这里主要讲讲上传成功后如何回调的问题。

CKEditor文件上传之后,服务端返回HTML文件,HTML文件包含JAVASCRIPT脚本,JS脚本会调用一个回调函数,若无错误,回调函数将返回的URL转交给CKEditor处理。

这3个参数依次是:

  • CKEditorFuncNum : 回调函数序号。CKEditor通过URL参数提交给服务端
  • URL : 上传后文件的URL
  • Error : 错误信息。若无错误,返回空字符串

使用蓝本
在大型应用中经常会使用蓝本,在蓝本视图中集成CKEditor的步骤和app视图基本相同。

1. 创建蓝本时需指明蓝本static目录的绝对路径

demo = Blueprint('demo', static_folder="/path/to/static")

2. 对应url需加上蓝本端点

<script src="{{url_for('.static', filename='ckeditor/ckeditor.js')}}"></script>

<script type="text/javascript">
  CKEDITOR.replace(
    "ckeditor_demo", {
      filebrowserUploadUrl: './ckupload/'
    }
  );
</script>

3. 设置endpoint端点值

response = form.upload(endpoint=demo)
Python 相关文章推荐
Python自动扫雷实现方法
Jul 25 Python
python安装oracle扩展及数据库连接方法
Feb 21 Python
Python实现查找匹配项作处理后再替换回去的方法
Jun 10 Python
python中join()方法介绍
Oct 11 Python
在PyCharm中三步完成PyPy解释器的配置的方法
Oct 29 Python
python实现海螺图片的方法示例
May 12 Python
python实现知乎高颜值图片爬取
Aug 12 Python
浅谈Tensorflow加载Vgg预训练模型的几个注意事项
May 26 Python
利用keras使用神经网络预测销量操作
Jul 07 Python
python 星号(*)的多种用途
Sep 21 Python
如何基于Python pygame实现动画跑马灯
Nov 18 Python
Django REST framework 限流功能的使用
Jun 24 Python
Linux中安装Python的交互式解释器IPython的教程
Jun 13 #Python
浅谈python中的面向对象和类的基本语法
Jun 13 #Python
深入理解python多进程编程
Jun 12 #Python
python中根据字符串调用函数的实现方法
Jun 12 #Python
python中函数总结之装饰器闭包详解
Jun 12 #Python
Python备份目录及目录下的全部内容的实现方法
Jun 12 #Python
深入理解python中的闭包和装饰器
Jun 12 #Python
You might like
PHP HTML代码串截取代码
2008/12/29 PHP
Yii PHP Framework实用入门教程(详细介绍)
2013/06/18 PHP
php number_format() 函数通过千位分组来格式化数字的实现代码
2013/08/06 PHP
php5.5中类级别的常量使用介绍
2013/10/02 PHP
PHP+Mysql+Ajax实现淘宝客服或阿里旺旺聊天功能(前台页面)
2017/06/16 PHP
PHP实现数组转JSon和JSon转数组的方法示例
2018/06/14 PHP
PHP设计模式之策略模式原理与用法实例分析
2019/04/04 PHP
基于jquery的图片的切换(以数字的形式)
2011/02/14 Javascript
jQuery EasyUI API 中文文档 - ProgressBar 进度条
2011/09/29 Javascript
Jquery 实现table样式的设定
2015/01/28 Javascript
jQuery使用slideUp方法实现控制元素缓慢收起
2015/03/27 Javascript
javascript正则表达式基础知识入门
2015/04/20 Javascript
JS绘制生成花瓣效果的方法
2015/08/05 Javascript
老生常谈JQuery data方法的使用
2016/09/09 Javascript
详解weex默认webpack.config.js改造
2018/01/08 Javascript
vue-cli 3.0 版本与3.0以下版本在搭建项目时的区别详解
2018/12/11 Javascript
angularjs请求数据的方法示例
2019/08/06 Javascript
Layui之table中的radio在切换分页时无法记住选中状态的解决方法
2019/09/02 Javascript
[05:08]顺网杯ISS-DOTA2赛歌 少女偶像Lunar青春演绎
2013/12/05 DOTA
[02:28]PWL开团时刻DAY3——Ink Ice与DeMonsTer之间的勾心斗角
2020/11/03 DOTA
[52:03]DOTA2-DPC中国联赛 正赛 Ehome vs iG BO3 第三场 1月31日
2021/03/11 DOTA
Python使用import导入本地脚本及导入模块的技巧总结
2019/08/07 Python
自适应线性神经网络Adaline的python实现详解
2019/09/30 Python
Python爬取微信小程序通用方法代码实例详解
2020/09/29 Python
澳大利高级泳装品牌:Bondi Born
2018/05/23 全球购物
跑步、骑行和铁人三项的高性能眼镜和服装:ROKA
2018/07/06 全球购物
英国家喻户晓的家居商店:The Range
2019/03/25 全球购物
Ticketmaster意大利:音乐会、节日、艺术和剧院的官方门票
2019/12/23 全球购物
介绍下Java的输入输出流
2014/01/22 面试题
集团公司人力资源部岗位职责
2014/01/03 职场文书
暑期培训随笔感言
2014/03/10 职场文书
李开复演讲稿
2014/05/24 职场文书
村长反四风问题个人对照检查材料
2014/09/21 职场文书
研讨会致辞
2015/07/31 职场文书
2016五一劳动节慰问信
2015/11/30 职场文书
个人向公司借款协议书
2016/03/19 职场文书