在这之前使用的编辑器是ueditor,是百度的;现在记录一下已经集成有段时间的 Editor.md 的 md 编辑器,确实好用!
在这之前,有个问题,数据库是保存 md 的还是保存 html 的,在网上看到过的方案:
- 保存两个字段:一个 md 的 ,一个 html 的;
- 保存md,每次阅读的时候现解析,会浪费cpu时间和资源;
- 保存 html,由于有文本字数限制,本来用户输入的字数符合要求,一解析成html,就超出数据库的长度设置了。
所以,选择哪种就就看自己的了;当然你也可以使用解析器(parsedown 解析器 将 Markdown 格式的内容快速转化成 HTML 格式)
Editor.md 不用那么麻烦了,它已经集成好了,我们调用就好了;
好了,下面开始我们的骚操作,一切都是瞬息,一切都将过去,痛苦总是那么短暂,快乐才是永恒源泉!你的骚不是我理解的骚!
在忧郁的日子里,甩甩头发,你总会觉得头脑清醒,却捂着胸口,暗自忧伤!其实内心里一直在怒吼、在流泪,我命由我,不由发;逼格野史,且行乐;
唉!好看的皮囊总是千篇一律,有趣的灵魂只剩我一个!谁说在不呢?就是就是,他们都没见识!骚嘿!
Editor.md的项目地址
1、下载与安装:
或者通过 NPM 安装:
npm install editor.md
或者通过 Bower 安装:
bower install editor.md
2、项目提炼
下载解压后会得到 editor.md-master 文件夹,它的目录:
本人整理的,命名为 editor.md ,目录为:
除了css 文件和 js 文件,其他都是源文件里拷贝过来的,
css:1、style.css 文件是原文件的 examples/css/style.css ;2、editormd.css 是原文件的 css/editormd.css,
js:1、editormd.js 文件是原文件的 editormd.js,2、jquery.min.js 文件是原文件的 examples/js/jquery.min.js。
3、编辑状态
在 editor.md 文件同目录下新建一个 md.html:
<html lang="zh-cn">
<head>
<title>editor.md 编辑器</title>
<link rel="stylesheet" href="editor.md/css/style.css">
<link rel="stylesheet" href="editor.md/css/editormd.css">
<script type="text/javascript" src="editor.md/js/jquery.min.js"></script>
<script type="text/javascript" src="editor.md/js/editormd.js"></script>
</head>
<body>
<div id="editormd">
<textarea class="editormd-html-textarea" name="content"></textarea>
</div>
<script type="text/javascript">
/* 编辑器 */
var testEditor;
$(function() {
testEditor = editormd("editormd", {
width : "100%",
height : 400,
syncScrolling : "single",
path : "editor.md/lib/",
saveHTMLToTextarea : true, // 开启获取 html 源码
flowChart : true,//控制流程图编辑
sequenceDiagram : true,//控制时序图编辑
taskList : true,//任务列表
tex : true,//科学公式
emoji : true,//moji表情
//htmlDecode : true,
htmlDecode : "style,script,iframe|on*", // 开启 HTML 标签解析,为了安全性,默认不开启
codeFold : true, //ctrl+q代码折叠
imageUpload : true,//开启本地图片上传
imageFormats : ["jpg", "jpeg", "gif", "png", "bmp", "webp"],
imageUploadURL : "/mdImage",//图片上传接口
dialogLockScreen : false, // 设置弹出层对话框不锁屏,全局通用,默认为true
dialogShowMask : false, // 设置弹出层对话框显示透明遮罩层,全局通用,默认为true
dialogDraggable : false, // 设置弹出层对话框不可拖动,全局通用,默认为true
dialogMaskOpacity : 0.4, // 设置透明遮罩层的透明度,全局通用,默认值为0.1
dialogMaskBgColor : "#000", // 设置透明遮罩层的背景颜色,全局通用,默认为#fff
//自定义工具栏
toolbarIcons:function(){
return [
"undo", "redo", "|",
"bold", "del", "italic", "quote", "ucwords", "uppercase", "lowercase", "|",
"h1", "h2", "h3", "h4", "h5", "h6", "|",
"list-ul", "list-ol", "hr", "|",
"link", "reference-link", "image", "code", "preformatted-text", "code-block", "table", "datetime", "emoji", "html-entities", "pagebreak", "|",
"goto-line", "watch", "preview", "fullscreen", "clear", "search", "|",
"help", "info","leftIcon","centerIcon","rightIcon"]
},
//如果没有图标,可以文字表述toolbarIconTexts:{ leftIcon:"left",},
toolbarIconsClass:{
leftIcon:"fa-align-left",
centerIcon:"fa-align-center",
rightIcon:"fa-align-right"
},
// 自定义工具栏按钮的事件处理
toolbarHandlers : {
leftIcon : function(cm, icon, cursor, selection) {
cm.replaceSelection("<p align='left'>" + selection + "</p>");
if(selection === "") {
cm.setCursor(cursor.line, cursor.ch + 16);
}
},
centerIcon : function(cm, icon, cursor, selection) {
cm.replaceSelection("<p align='center'>" + selection + "</p>");
if(selection === "") {
cm.setCursor(cursor.line, cursor.ch + 18);
}
},
rightIcon : function(cm, icon, cursor, selection) {
cm.replaceSelection("<p align='right'>" + selection + "</p>");
if(selection === "") {
cm.setCursor(cursor.line, cursor.ch + 17);
}
}
},
lang : {
toolbar : {
leftIcon:"居左",
centerIcon:"居中",
rightIcon:"居右"
}
},
});
testEditor.getMarkdown(); //获取md
testEditor.getHTML(); //获取html
});
//testEditor.setMarkdown('');//清空编辑框的内容
</script>
</body>
</html>
4、图片上传
php:
public function mdImage(){
//实例化存储引擎
//接收字段为什么是editormd-image-file???
$file =$this->request->file('editormd-image-file');
// 移动到框架应用根目录/uploads/ 目录下
$info = $file->validate(['ext'=>'jpg,jpeg,png,gif'])->rule('sha1')->move($this->dirFile());
if($info){
// 成功上传后 获取上传信息
$res = $info->getSaveName();
//返回值文档上面规定的格式是
return json(['success' => 1,'message' => '上传成功!',"url"=>'/uploads/Markdown/'.date('Ym').'/'.$res]);
}else{
// 上传失败获取错误信息
$res = $file->getError();
return $this->error($res);
}
}
5、页面渲染(md => html)
<html lang="zh-cn">
<head>
<title>editor.md 渲染 html </title>
</head>
<body>
<div class="md_html" id="md_html">
<textarea style="display:none;">{$data.content}</textarea>
</div>
</body>
<!--引入md转html的css、js文件-->
<link rel="stylesheet" href="editor.md/css/editormd.css" />
<script src="editor.md/js/editormd.js"></script>
<script src="editor.md/lib/marked.min.js"></script>
<script src="editor.md/lib/prettify.min.js"></script>
<script src="editor.md/lib/raphael.min.js"></script>
<script src="editor.md/lib/underscore.min.js"></script>
<script src="editor.md/lib/sequence-diagram.min.js"></script>
<script src="editor.md/lib/flowchart.min.js"></script>
<script src="editor.md/lib/jquery.flowchart.min.js"></script>
<script type="text/javascript" src="editor.md/js/jquery.min.js"></script>
<script type="text/javascript">
editormd.markdownToHTML('md_html',{
htmlDecode: "style,script,iframe", //可以过滤标签解码
emoji: true,
taskList: true,
tex: true,
flowChart: true,
sequenceDiagram: true,
});
</script>
</html>
6、后端接收数据
内容类型:
markdown:input("content"); // name 名称
html: input("editormd-html-code"); // ID-html-code
哎,你说世面是什么?见过世面!不就是一个人自身对世界的认识、经验什么的。
这写一大堆的,什么鬼啊,辣条!... 我觉得,真的!