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里对list中的整数求平均并排序
Sep 12 Python
Python制作爬虫采集小说
Oct 25 Python
Python使用Paramiko模块编写脚本进行远程服务器操作
May 05 Python
pycharm远程linux开发和调试代码的方法
Jul 17 Python
python使用for循环计算0-100的整数的和方法
Feb 01 Python
python跳出双层for循环的解决方法
Jun 24 Python
python3 线性回归验证方法
Jul 09 Python
对django views中 request, response的常用操作详解
Jul 17 Python
python 默认参数相关知识详解
Sep 18 Python
学Python 3的理由和必要性
Nov 19 Python
PyCharm设置注释字体颜色以及是否倾斜的操作
Sep 16 Python
Python更改pip镜像源的方法示例
Dec 01 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+javascript实现二级级联菜单的制作
2008/05/06 PHP
超级简单的php+mysql留言本源码
2009/11/11 PHP
php简单实现发送带附件的邮件
2015/06/10 PHP
Laravel学习教程之路由模块
2017/08/18 PHP
ThinkPHP框架获取最后一次执行SQL语句及变量调试简单操作示例
2018/06/13 PHP
CSS和JS标签style属性对照表(方便js开发的朋友)
2010/11/11 Javascript
jquery使用ColorBox弹出图片组浏览层实例演示
2013/03/14 Javascript
javascript时间函数基础介绍
2013/03/28 Javascript
Javascript之this关键字深入解析
2013/11/12 Javascript
JavaScript实现弹出子窗口并传值给父窗口
2014/12/18 Javascript
JavaScript中的cacheStorage使用详解
2015/07/29 Javascript
js中获取键盘按下键值event.keyCode、event.charCode和event.which的兼容性详解
2017/03/15 Javascript
浅析Proxy可以优化vue的数据监听机制问题及实现思路
2018/11/29 Javascript
layui写后台表格思路和赋值用法详解
2019/11/14 Javascript
如何基于原生javaScript生成带图片的二维码
2019/11/21 Javascript
vue实现的封装全局filter并统一管理操作示例
2020/02/02 Javascript
[48:32]2018DOTA2亚洲邀请赛 3.31 小组赛 A组 LGD vs VG
2018/04/01 DOTA
Python实现自动上京东抢手机
2018/02/06 Python
django缓存配置的几种方法详解
2018/07/16 Python
tensorflow实现简单逻辑回归
2018/09/07 Python
python实现LBP方法提取图像纹理特征实现分类的步骤
2019/07/11 Python
python实现动态数组的示例代码
2019/07/15 Python
python双向链表原理与实现方法详解
2019/12/03 Python
pytorch动态网络以及权重共享实例
2020/01/06 Python
python自动化unittest yaml使用过程解析
2020/02/03 Python
pytorch SENet实现案例
2020/06/24 Python
Pytorch损失函数nn.NLLLoss2d()用法说明
2020/07/07 Python
Bergfreunde丹麦:登山装备网上零售商
2017/02/26 全球购物
Rhone官方网站:男士运动服装、健身服装和高级运动服
2019/05/01 全球购物
西安夏日科技有限公司Java笔试题
2013/01/11 面试题
英语专业毕业个人求职自荐信
2013/09/21 职场文书
文明风采获奖感言
2014/02/18 职场文书
技校毕业生个人学习的自我评价
2014/02/21 职场文书
城市规划应届生推荐信
2014/09/08 职场文书
党小组推荐意见
2015/06/02 职场文书
关于Python中*args和**kwargs的深入理解
2021/08/07 Python