editor.md构建前端mdeditor编辑工具

2020年5月31日 13:50 阅读 211 评论 0

此类文章有很多,推荐隔壁的https://tendcode.com/article/markdown-editor/ ,因为他的文章发布在我之前,声明一下,估计大部分都有重复。 这篇文章我是想为后续地开发来作铺垫。

editor.md 使用

我选择了一个叫做 editor.md 的开源项目作为编辑器支持,这个项目的 github 地址是 editor.md 该项目的说明也很明确,这个编辑器就是一个组件,所以非常适合放到线上使用。大家可以直接去下载editor.md的源码包,并进行开发。https://github.com/pandao/editor.md

值得注意的是我们使用的css和js,和django-mdeditor这个包是一样的。 运行python manage.py collectstatic将django-mdeditor的静态文件集合到我们设置中的主static中,这样我们就可以在下面调用css和js文件惹。

通过官方的文档我们可以大概得知,配置一个简单的md编辑网页的话我们需要编辑一个新的前端界面

md2html.html:

{% extends "base.html" %}
{% load static %}
{% block head_title %}
在线md2html工具 | 娃哈哈'店长'的个人博客
{% endblock %}
{% block metas %}
    <meta name="description"  content="在线md2html工具" />
    <meta name="keywords"  content="mdeditor、在线md2html平台、" />
{% endblock %}
{% block top_file %}
    <link href="{% static 'mdeditor/css/editormd.css' %}" rel="stylesheet" type="text/css">
    <style type="text/css">
        #test-editormd {
            z-index: 100;
        }
    </style>
{% endblock %}
{% block mdeditor_contain %}
<div id="layout" style="width: 100%;">
    <div id="test-editormd" >   
        <textarea style="display:none;" ></textarea>
    </div>
</div> 
{% endblock %}     
{% block end_file %}
<!-- 基础文件 -->
<!-- <script src="{% static 'mdeditor/js/jquery.min.js' %}"></script> -->
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
<script src="{% static 'mdeditor/js/editormd.min.js' %}"></script>
<script src="{% static 'mdeditor/js/lib/raphael.min.js' %}"></script>
<!-- 绘制序列图 -->
<script src="{% static 'mdeditor/js/lib/sequence-diagram.min.js' %}"></script>
<!-- 绘制流程图 -->
<script src="{% static 'mdeditor/js/lib/flowchart.min.js' %}"></script>
<script src="{% static 'mdeditor/js/lib/jquery.flowchart.min.js' %}"></script>
<!-- <script src="{% static 'mdeditor/js/lib/underscore.min.js' %}"></script> -->
<!-- <script src="{% static 'mdeditor/js/lib/marked.min.js' %}"></script> -->
<!-- <script src="{% static 'mdeditor/js/lib/prettify.min.js' %}"></script> -->
<script type="text/javascript">
    var testEditor;
    $(function() {    
        // You can custom @link base url.

        testEditor = editormd("test-editormd", {
            width     : "90%",
            path : "{% static 'mdeditor/js/lib/' %}",
            height    : 720,
            toc       : false,
            // //atLink    : false,    // disable @link
            // //emailLink : false,    // disable email address auto link
            syncScrolling       : 'single',
            todoList  : true,
            // theme : "dark",
            // previewTheme : "dark",
            // editorTheme : "pastel-on-dark",
            // markdown : md,
            codeFold : true,
            // //syncScrolling : false,
            saveHTMLToTextarea : true,    // 保存 HTML 到 Textarea
            searchReplace : true,
            // 开启工具栏固定定位
            toolbarAutoFixed: false,
            // //watch : false,                // 关闭实时预览
            // htmlDecode : "style,script,iframe|on*",            // 开启 HTML 标签解析,为了安全性,默认不开启    
            // //toolbar  : false,             //关闭工具栏
            // //previewCodeHighlight : false, // 关闭预览 HTML 的代码块高亮,默认开启
            emoji : true,
            taskList : true,
            tocm            : false,         // Using [TOCM]
            tex : true,                   // 开启科学公式TeX语言支持,默认关闭
            flowChart : true,             // 开启流程图支持,默认关闭
            sequenceDiagram : true,       // 开启时序/序列图支持,默认关闭,
            imageUpload : true,
            imageUploadURL: "/tool/default_upload/", //图片上传后台地址
        });


    });
</script>
{% endblock %}

上传图片路由

细心的同学可以发现,我们开启了上传图片功能。但是图片上传对应的是一个post请求,原editor.md项目种得请i求是通过php文件编写的。这里我们学习django-mdeditor中的请求路由,我们重新定义一个请求的url:"/tool/default_upload/",我们在app为tool下的views.py文件中编写:

from django.http import HttpResponse
from django.conf import settings
import datetime
import json, os
from mdeditor.views import UploadView
class default_upload(UploadView):
    """ upload image file """
    @method_decorator(csrf_exempt)
    def dispatch(self, *args, **kwargs):
        return super(default_upload, self).dispatch(*args, **kwargs)

    def post(self, request, *args, **kwargs):
        upload_image = request.FILES.get("editormd-image-file", None)
        media_root = settings.MEDIA_ROOT
        # image none check
        if not upload_image:
            return HttpResponse(json.dumps({
                'success': 0,
                'message': "未获取到要上传的图片",
                'url': ""
            }))

        # image format check
        file_name_list = upload_image.name.split('.')
        file_extension = file_name_list.pop(-1)
        # 替换上传图片名中非数字和字母的字符为'_'字符
        file_name_list = ["".join(filter(str.isalnum, _))
                          for _ in file_name_list]
        file_name = '.'.join(file_name_list)

        if file_extension not in ["jpg", "JPG", "jpeg", "JPEG", "gif", "GIF", "png", "PNG", "bmp", "BMP", "webp", "WEBP"]:
            return HttpResponse(json.dumps({
                'success': 0,
                'message': "上传图片格式错误,允许上传图片格式为:%s" % ','.join(
                    ["jpg", "JPG", "jpeg", "JPEG", "gif", "GIF", "png", "PNG", "bmp", "BMP", "webp", "WEBP"]),
                'url': ""
            }))

        # image floder check
        file_path = os.path.join(media_root, 'mdeditor/uploads', '{0:%Y%m%d}'.format(
            datetime.datetime.now()))
        if not os.path.exists(file_path):
            try:
                os.makedirs(file_path)
            except Exception as err:
                return HttpResponse(json.dumps({
                    'success': 0,
                    'message': "上传失败:%s" % str(err),
                    'url': ""
                }))

        # save image
        file_full_name = '%s_%s.%s' % (file_name,
                                       '{0:%Y%m%d%H%M}'.format(
                                           datetime.datetime.now()),
                                       file_extension)
        if not os.path.exists(os.path.join(file_path, file_full_name)):
            with open(os.path.join(file_path, file_full_name), 'wb+') as file:
                for chunk in upload_image.chunks():
                    file.write(chunk)
        res = HttpResponse(json.dumps({'success': 1,
                                       'message': "上传成功!",
                                       'url': '{0}{1}{2}/{3}/{4}'.format(settings.DOMAIN_NAME, settings.MEDIA_URL,
                                                                         'mdeditor/uploads', '{0:%Y%m%d}'.format(
                                           datetime.datetime.now()),
                                           file_full_name)}))
        return res

判断上传文件的格式:

if file_extension not in ["jpg", "JPG", "jpeg", "JPEG", "gif", "GIF", "png", "PNG", "bmp", "BMP", "webp", "WEBP"]:

按照日期分批存放上传的图片,2020年5月29日上传的图片就存放在

file_path = os.path.join(media_root, 'mdeditor/uploads', '{0:%Y%m%d}'.format(
            datetime.datetime.now()))

构造http请求返回json数据:

HttpResponse(json.dumps({'success': 1,
                                       'message': "上传成功!",
                                       'url': '{0}{1}{2}/{3}/{4}'.format(settings.DOMAIN_NAME, settings.MEDIA_URL,
                                                                         'mdeditor/uploads', '{0:%Y%m%d}'.format(
                                           datetime.datetime.now()),
                                           file_full_name)}))

在settings.py文件中添加:

# 服务器域名
DOMAIN_NAME = 'http://boywithacoin.cn'

这样当我们上传完图片后,返回的url就带有我们的域名了:https://boywithacoin.cn/media/mdeditor/article/20200601/file1590995937000_202006011518.png,否则为/media/mdeditor/article/20200601/file1590995937000_202006011518.png,这样的好处时,当我们将前端编辑的mardown的内容copy到别的平台时也能访问

原创文章,转载请注明出处:https://boywithacoin.cn/article/editor-mdgou-jian-qian-duan-mdeditorbian-ji-gong-ju/


您尚未登录,请 登录注册 后评论
    0 人参与 | 0 条评论
    暂时没有评论,欢迎来尬聊!