为 Flask 编写一个百度编辑器的插件

Posted Python开发者

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为 Flask 编写一个百度编辑器的插件相关的知识,希望对你有一定的参考价值。

来源:我勒个去 

链接:https://segmentfault.com/a/1190000005755062


近期项目开发中,隔壁那个搞python的哥们竟然笑着对我说,希望我能给他写1个百度编辑器的demo,方便他直接调用。


当时真的受宠若惊,这哥们实力不在我之下,只能答应它了。上网搜索下,有1篇文章Flask项目集成富文本编辑器UEditor实现图片上传功能(http://flask123.sinaapp.com/article/47/)已经有1个现成的例子了。


这篇文章的作者,直接在视图中定义对应的操作,进行一系列图片上传功能的。但是,这并没有满足我的要求,我想要的想过是直接导入一个模块,然后它帮我做完一切的事情。比如这样的形式:


from xxx import yyy

 

app = Flask(__name__)

yyy(app)


于是只好从头开始学习。


这里,我按照如下的方式从头编写1个Flask版本的百度编辑器的插件:


  • 百度文档的解读

  • 后端实际代码的编写

  • 前端代码的编写


下面我们开始我们编写插件的过程。


百度文档的解读


在百度文档中,已经说明UEditor提供4种后台语言,分别为php,asp,asp.net和jsp。首先需要配置serverUrl参数,当ueditor初始化会向serverUrl中的URL发起对后端配置的请求。

而配置的优先级如下:


后端获取的配置项 > 实例化传入的配置项 > ueditor.config.js文件的配置项

 

可以看到,后端获取的配置项优先级是最高的。在对后端配置请求的过程中,会对配置文件config.json中的设置进行读取。

而在请求的过程中,百度文档统一请求格式说明中已经说明,通过GET请求上的action参数来判断是什么类型的请求。后端根据不同的请求,进行对应的处理后,需要返回给定格式的内容给前端javascript。返回的结果一般为JSON的形式。


实现目标


现在我们已经对百度编辑器UEditor的文档进行了初步的解读,下面我们开始编写我们实际的代码。


在这里,我们主要会用到config和uploadimage这2个配置,其他功能留给读者自己去实现。


实际代码的编写


在编写代码之前,我打算这样来实现这个插件:


  • 配置文件为1个python的模块

  • 有1个模块用于处理对应请求的操作

  • 有1个模块用于处理图片上传的操作,这里直接拿取之前Flask文档作者中的上传模块


然后我们逐一进行讲解。


配置文件


这里,我打算将百度默认提供的配置写入到1个config的模块中,本来打算使用类似如下的方式:


imageAction = "uploadimage"

imageFieldName = "upfile"

...


由于时间比较紧,一时半会做不到Flask中读取配置文件后为1个字典的形式,因此简化为该模块直接返回1个字典,如下所示:


CONFIG = dict(imageActionName = "uploadimage", # 执行上传图片的action名称

              imageFieldName = "upfile",       #提交的图片表单名称

              imageMaxSize = 2048000,         #上传大小限制,单位B

              imageAllowFiles = ['.png', '.jpg', '.jpeg', '.gif', '.bmp'], #上传图片格式显示

              imageCompressEnable = True,      #是否压缩图片,默认是true

              imageCompressBorder = 1600,      #图片压缩最长边限制

              imageInsertAlign = "none",      #插入的图片浮动方式

              imageUrlPrefix = "",             #图片访问路径前缀

              imagePathFormat = "upload/{yyyy}/{mm}/{dd}/{time}{rand:6}"              

              )


我们将这段代码定义为config模块中,这样,我们就完成了配置模块的内容了。


处理请求


这里我们定义1个ueditor的模块用于我们处理请求的操作。这里,我定义了1个UEditor的类用于处理这个操作:


class UEditor(object):

    pass


首先我们要做的第一步是解决请求参数的问题,让不同的请求调用不同的处理函数,我们将其定义在该类的get_action函数中:


    def get_action(self):

        action = request.args.get('action')

        if action:

            return self.handle(action)


我们将具体处理的过程放在handle函数中,在这个函数中,我们要做2件事情:


  • 根据不同的请求参数调用不同的函数

  • 将不同函数返回的结果返回给调用者


然后是handle函数其具体的源码:


    def handle(self, action):

        if action == 'config':

            result = get_config()

        elif action == 'uploadimage':

            result = upload_image()

        else:

            result = {'state': '未实现'}

        res = make_response(json.dumps(result))

        res.headers['Access-Control-Allow-Origin'] = '*'

        res.headers['Access-Control-Allow-Headers'] = 'X-Requested-With,X_Requested_With'

        return res


可以看到,这部分的源码和我们之前编写的并没有什么不同。在action时我们应该将配置文件中的内容直接返回即可:


def get_config():

    return CONFIG


而在上传图片的时候,我们根据配置文件中的配置,将其传递给上传文件的模块,这里我们直接把之前Flask那篇文章作者git上的Uploader拿了过来。其实他也是参考php的实现的源码,将其修改为python版本而言。


def upload_image():

    """上传图片"""

    fieldName = CONFIG.get('imageFieldName')

    conf = dict(pathFormat = CONFIG.get('imagePathFormat'),

                maxSize = CONFIG.get('imageMaxSize'),

                allowFiles = CONFIG.get('imageAllowFiles')

                )

    if request.files.get(fieldName):

        field = request.files[fieldName]

        uploader = Uploader(field, conf, 'static')

        result = uploader.getFileInfo()

    else:

        result = {'state': '上传接口出错'}

    return result


这里,在Uploader类中第1个参数为类文件对象,第2个参数为对应的配置,第3个参数为图片上传的根目录。最后,通过这个实例的getFileInfo方法得到后端上传成功后返回的内容。

这样,我们就基本解决了后端图片上传的过程了。但是,前端的调用问题我们完全还没有涉及到,下面我们来说说前端的调用问题。


前端调用



<script type="text/javascript" charset="utf-8" src="static/ueditor.config.js"></script>

<script type="text/javascript" charset="utf-8" src="static/ueditor.all.min.js"> </script>

<script type="text/javascript" charset="utf-8" src="static/lang/zh-cn/zh-cn.js"></script>

 

<div>

    <div id="editor" style="height:400px;"></div>

</div>

 

<script type="text/javascript">

    var ue = UE.getEditor('editor', {

        serverUrl: "xxxx/yyyyy"

    });

</script>


之前我们后端代码的过程只解决了图片上传的问题,关于serverUrl关联到对应URL的问题还一直没有解决。

为了解决这个问题,我打算引入蓝图和Flask提供的add_url_rule来解决这个问题。


UE = Blueprint('ueditor', __name__, url_prefix= '/ueditor')

 

...

 

def init_app(self,app):

    self.app = app

    UE.add_url_rule('/upload/'

                   'uploads',

                   self.get_action, methods = ['POST', 'GET', 'OPTIONS'])

    self.app.register_blueprint(UE)



总结


最后,我们总结下这个插件的使用方法,我们新建1个app模块,其源码类似如下:


from flask import Flask, render_template

from ueditor import UEditor

 

app = Flask(__name__)

ue = UEditor(app)

 

@app.route('/')

def index():

    return render_template('index.html')


在这里,我们引入我们之前编写的插件模块,然后将其实例化操作。而在index.html文件中则为我们之前引入百度编辑器的内容。

在这里index.html的内容类似如下:


<script type="text/javascript" charset="utf-8" src="/static/ueditor/ueditor.config.js"></script>

<script type="text/javascript" charset="utf-8" src="/static/ueditor/ueditor.all.min.js"> </script>

<script type="text/javascript" charset="utf-8" src="/static/ueditor/lang/zh-cn/zh-cn.js"></script>

 

<div>

    <div id="editor" style="height:400px;"></div>

    <button id="submit">提交</button>

</div>

<script type="text/javascript">

    var ue = UE.getEditor('editor', {

        serverUrl: "/ueditor/upload/"

    });

</script>


这样我们便完成了百度编辑器的1个插件的编写了。


参考文章:


http://fex-team.github.io/ueditor/#server-deploy

http://fex-team.github.io/ueditor/#server-config

http://fex-team.github.io/ueditor/#dev-request_specification


【今日微信公号推荐↓】

更多推荐请看


以上是关于为 Flask 编写一个百度编辑器的插件的主要内容,如果未能解决你的问题,请参考以下文章

Textarea - 百度富文本编辑器插件UEditor

如何用百度UEditor编辑器替换WordPress编辑器

百度编辑器ueditor插件的基本使用

百度富文本编辑器支持从word复制粘贴保留格式和图片的插件

Js 之百度编辑器UEditor插件

Ueditor百度富文本编辑器添加h5手机端预览功能