们经常可以看到各个博客网站中用于编辑文章的富文本编辑器,在富文本编辑器中,我们可以对我们的编辑内容样式进行设置。富文本编辑器一般是通过插件来实现的,我们只需要在页面中配置一下插件提供的一些API即可。
本例中使用Editormd来演示如何配置使用富文本编辑器。
Editormd简介
Editormd是国内开源的一款在线Markdown编辑器,可嵌入的 Markdown 在线编辑器(组件),基于 CodeMirror、jQuery 和 Marked 构建。
支持“标准”Markdown / CommonMark和Github风格的语法,也可变身为代码编辑器。
官网地址:https://pandao.github.io/editor.md/
创建文章表
在使用富文本编辑器之前,先来创建一个文章表article,这里只添加了最基本的几个字段, 以后想要扩展的话还可以添加标签、时间、浏览量、点赞、评论等字段。建表SQL如下:
CREATE TABLE article(
id int(10) NOT NULL AUTO_INCREMENT COMMENT '文章唯一id',
author varchar(50) NOT NULL COMMENT '作者',
title varchar(100) NOT NULL COMMENT '标题',
content longtext NOT NULL COMMENT '文章内容'
PRIMARY KEY (id)
)ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8建完表,我们就可以开始编写代码来使用富文本编辑器了。
配置使用
1、创建一个SpringBoot项目,配置数据库连接,我们这里连接的是MyBatis(注意MySQL8需要在url中配置时区)。
spring:
datasource:
username: root
password: 123456
#?serverTimezone=UTC解决时区的报错
url: jdbc:mysql://localhost:3306/springboot?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
driver-class-name: com.mysql.cj.jdbc.Driver
thymeleaf:
cache: false
mybatis:
mapper-locations: classpath:com/wunian/mapper/*.xml
type-aliases-package: com.wunian.pojo2、导入Editormd静态资源,静态资源的目录结构如下图所示。
3、编写文章编辑页面editor.html,引入Editormd的CSS和js文本,添加Editormd配置。
<!DOCTYPE html>
<html class="x-admin-sm" lang="zh" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>及时雨的Blog</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width,user-scalable=yes, minimum-scale=0.4, initial-scale=0.8,target-densitydpi=low-dpi" />
<!--Editor.md-->
<link rel="stylesheet" th:href="@{/editormd/css/editormd.css}"/>
<link rel="shortcut icon" href="https://pandao.github.io/editor.md/favicon.ico" type="image/x-icon" />
</head>
<!--写博客页面-->
<body>
<div class="layui-fluid">
<div class="layui-row layui-col-space15">
<div class="layui-col-md12">
<!--博客表单-->
<form name="mdEditorForm">
<div>
标题: <input type="text" name="title">
</div>
<div>
作者: <input type="text" name="author">
</div>
<!-- 文章的主体内容 textarea -->
<div id="article-content">
<textarea name="content" id="content" style="display:none;"> </textarea>
</div>
</form>
</div>
</div>
</div>
</body>
<!--editormd-->
<script th:src="@{/editormd/jquery.min.js}"></script>
<script th:src="@{/editormd/editormd.js}"></script>
<script type="text/javascript">
var testEditor;
$(function() {
//这是一个最简单的Editormd配置,往后我们要修改Editormd的
//功能或者样式,就改这里的配置就可以了
testEditor = editormd("article-content", {
width : "90%",
height : 640,
syncScrolling : "single",
path : "../editormd/lib/"
});
</script>
</html>4、上面配置的只是最简单的富文本编辑器功能,我们可以添加更多的配置来增加功能。
<script type="text/javascript">
var testEditor;
//window.onload = function(){ }
$(function() {
testEditor = editormd("article-content", {
width : "95%",
height : 500,
syncScrolling : "single",
path : "../editormd/lib/",
// 自定义的增强配置!
saveHTMLToTextarea : true, // 保存 HTML 到 Textarea
emoji: true, // 开启表情的功能! 图片的本地配置!
// theme: "light",//工具栏主题
// previewTheme: "dark",//预览主题
// editorTheme: "pastel-on-dark",//编辑主题
// markdown的配置!
tex : true, // 开启科学公式TeX语言支持,默认关闭
flowChart : true, // 开启流程图支持,默认关闭
sequenceDiagram : true, // 开启时序/序列图支持,默认关闭,
//图片上传
imageUpload : true,
imageFormats : ["jpg", "jpeg", "gif", "png", "bmp", "webp"],
imageUploadURL : "/article/file/upload", // 文件上传的处理请求!
onload : function() {
console.log('onload', this);
},
/*指定需要显示的功能按钮*/
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",
"releaseIcon", "index"]
},
// 这里的自定义功能就好比,Vue 组件
/*自定义功能按钮,下面我自定义了2个,一个是发布,一个是返回首页*/
toolbarIconTexts : {
releaseIcon : "<span bgcolor=\"gray\">发布</span>",
index : "<span bgcolor=\"red\">返回首页</span>",
},
/*给自定义按钮指定回调函数*/
toolbarHandlers:{
releaseIcon : function(cm, icon, cursor, selection) {
//表单提交
mdEditorForm.method = "post";
mdEditorForm.action = "/article/addArticle";//提交至服务器的路径
mdEditorForm.submit();
},
index : function(){
window.location.href = '/';
},
}
});
});
</script>5、由于表情包的加载地址在国外,因此有时候可能加载不出来,我们可以把表情包下载到本地,放到/static/editormd/plugins/emoji-dialog/emoji目录下,并修改editormd.js中的表情加载路径为我们的表情包存放的目录路径。
editormd.emoji = {
path : "../editormd/plugins/emoji-dialog/emoji/",
ext : ".png"
};6、上传图片功能需要进行配置,我们可以在当前项目目录下建立upload文件夹来上传文件(注意这里应该手动建立目录,不要使用代码创建),然后配置一下虚拟路径(需要自定义WebMVC配置类)。
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
// 文件保存在真实目录/upload/下,
// 访问的时候使用虚路径/upload,比如文件名为1.png,就直接/upload/1.png就ok了。
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/upload/**")
.addResourceLocations("file:"+System.getProperty("user.dir")+"/upload/");
}
}7、在Controller中编写文件上传的请求方法。
// MarkDown博客图片上传问题
@RequestMapping("/file/upload")
@ResponseBody
public JSONObject fileUpload(@RequestParam(value = "editormd-image-file", required = true) MultipartFile file, HttpServletRequest request) throws IOException {
//上传路径保存设置
//获得SpringBoot当前项目的路径:System.getProperty("user.dir")
String path = System.getProperty("user.dir")+"/upload/";
//按照月份进行分类:
Calendar instance = Calendar.getInstance();
String month = (instance.get(Calendar.MONTH) + 1)+"月";
path = path+month;
File realPath = new File(path);
if (!realPath.exists()){
realPath.mkdirs();
}
//上传文件地址
System.out.println("上传文件保存地址:"+realPath);
//解决文件名字问题:我们使用uuid;
String filename = "ks-"+UUID.randomUUID().toString().replaceAll("-", "")+".jpg";
//通过CommonsMultipartFile的方法直接写文件(注意这个时候)
file.transferTo(new File(realPath +"/"+ filename));
//给editormd进行回调
JSONObject res = new JSONObject();
res.put("url","/upload/"+month+"/"+ filename);
res.put("success", 1);
res.put("message", "upload success!");
return res;
}8、编写文章显示页面article.html,同样需要配置Editormd来正常显示一些MarkDown文本。
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title th:text="${article.title}"></title>
</head>
<!--读博客的页面-->
<body>
<div>
<!--文章头部信息:标题,作者,最后更新日期,导航-->
<h2 style="margin: auto 0" th:text="${article.title}"></h2>
作者:<span style="float: left" th:text="${article.author}"></span>
<!--文章主体内容-->
<div id="doc-content">
<textarea style="display:none;" placeholder="markdown" th:text="${article.content}"></textarea>
</div>
</div>
<!--固定editormd依赖! -->
<link rel="stylesheet" th:href="@{/editormd/css/editormd.preview.css}"/>
<script th:src="@{/editormd/jquery.min.js}"></script>
<script th:src="@{/editormd/lib/marked.min.js}"></script>
<script th:src="@{/editormd/lib/prettify.min.js}"></script>
<script th:src="@{/editormd/lib/raphael.min.js}"></script>
<script th:src="@{/editormd/lib/underscore.min.js}"></script>
<script th:src="@{/editormd/lib/sequence-diagram.min.js}"></script>
<script th:src="@{/editormd/lib/flowchart.min.js}"></script>
<script th:src="@{/editormd/lib/jquery.flowchart.min.js}"></script>
<script th:src="@{/editormd/editormd.js}"></script>
<script type="text/javascript">
var testEditor;
$(function () {
// 绑定我们要渲染页面的 div
testEditor = editormd.markdownToHTML("doc-content", {//注意:这里是上面DIV的id
htmlDecode: "style,script,iframe",
emoji: true,
taskList: true,
tocm: true,
tex: true, // 默认不解析
flowChart: true, // 默认不解析
sequenceDiagram: true, // 默认不解析
codeFold: true
});
});
</script>
</body>
</html>9、最后别忘了编写保存文章和显示文章的Controller请求方法。
博客文章写作过程中,一直再寻找一个合适的编辑器。先后尝试了wangEditor、layui-Editor在用户页面得到应用。但文章的整洁程度难以和markdown媲美。mdendtor是个不错的选择,在安装完Django-enditor之后,最大的难题就是前端显示了。最初引入python库markdown,转化效果不是很理想。紧接着找到前端js对应的showdown.js库,显示效果依旧不好。于是,想到后台的预览窗口是怎么显示,直接把mdeditor的js抄到前端就行了。
安装django-mdeditor
pip install django-mdeditor
添加app到sittings
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', ...... 'django.contrib.sitemaps', 'mdeditor', # mdeditor编辑器 ]
修改model
from mdeditor import fields as md_models class Article(models.Model): id = models.AutoField(primary_key=True, max_length=32) ...... content = md_models.MDTextField(verbose_name='正文', blank=False) ......
此时,刷新后端就显示正常了
找到需要的js和css
在site-packages目录下找到如下js和css
mdeditor\static\mdeditor\js\lib\marked.min.js mdeditor\static\mdeditor\js\editormd.js mdeditor\static\mdeditor\css\editormd.preview.css
找到之后放到static目录下并在相应页面引入
前端适配
css和js处理
<!--引入样式文件-->
<link rel="stylesheet" href="/static/editor.md-master/css/editormd.preview.css"/>
<!--引入js文件-->
<script src="/static/editor.md-master/lib/marked.min.js"></script>
<script src="/static/editor.md-master/editormd.js"></script>
<!--处理逻辑-->
<script>
editormd.markdownToHTML("article_content", { //article_content是html文档的ID
emoji: true,
taskList: true,
});
</script>
html的处理
需要注意的是:style里面所有的内容不能少,否则造成样式会扭曲。textarea标签不能缺少,不然会造成代码的不识别。
<div id="article_content"
style="-webkit-box-sizing: border-box;-moz-box-sizing: border-box;box-sizing: border-box;">
<textarea style="display:none">{{ article.content | safe}}</textarea>
</div>
后续注意
这样还不够,原作者这个markdownToHTML的方法并未考虑兼容原有纯HTML的文章。这样会造成我们非MD格式的文章样式上出现扭曲。此时可以打开editormd.js这个文件,搜索editormd.markdownToHTML方法。
在 var markdownDoc = (settings.markdown === "") ? saveTo.val() : settings.markdown;代码的下一行添加
if(markdownDoc.startsWith('<') || markdownDoc.endsWith('>')){
$("#" + id).html(markdownDoc)
return
}
这样解决下来并不是很完美,最好判断下这个文章是不是一个XML文档比较稳妥,技术有限不能解决。留给你解决
译自: https://opensource.com/article/18/8/markdown-html-publishing
作者: Peter Cheer
译者: geekpi
用这个有用工具从 Markdown 文件创建一个基础的网站。
有很多理由喜欢 Markdown,这是一门简单的语言,有易于学习的语法,它可以与任何文本编辑器一起使用。使用像 Pandoc 这样的工具,你可以将 Markdown 文本转换为 各种流行格式 ,包括 HTML。你还可以在 Web 服务器中自动执行转换过程。由 TimoDörr 创建的名为 MDwiki 的 HTML5 和 JavaScript 应用可以将一堆 Markdown 文件在浏览器请求它们时转换为网站。MDwiki 网站包含一个操作指南和其他信息可帮助你入门:
Mdwiki 网站的样子。
在 Web 服务器内部,基本的 MDwiki 站点如下所示:
该站点的 web 服务器文件夹的样子
我将此项目的 MDwiki HTML 文件重命名为 START.HTML。还有一个处理导航的 Markdown 文件和一个 JSON 文件来保存一些配置设置。其他的都是网站内容。
虽然整个网站设计被 MDwiki 固定了,但内容、样式和页面数量却没有。你可以在 MDwiki 站点 查看由 MDwiki 生成的一系列不同站点。公平地说,MDwiki 网站缺乏网页设计师可以实现的视觉吸引力 —— 但它们是功能性的,用户应该平衡其简单的外观与创建和编辑它们的速度和简易性。
Markdown 有不同的风格,可以针对不同的特定目的扩展稳定的核心功能。MDwiki 使用 GitHub 风格 Markdown ,它为流行的编程语言添加了格式化代码块和语法高亮等功能,使其非常适合生成程序文档和教程。
MDwiki 还支持 “gimmick”,它增加了如嵌入 YouTube 视频和显示数学公式等额外功能。如果在某些项目中需要它们,这些值得探索。我发现 MDwiki 是创建技术文档和教育资源的理想工具。我还发现了一些可能不会立即显现出来的技巧和 hack。
当部署在 Web 服务器中时,MDwiki 可与任何现代 Web 浏览器一起使用。但是,如果你使用 Mozilla Firefox 访问 MDwiki,那么就不需要 Web 服务器。大多数 MDwiki 用户会选择在 Web 服务器上部署完整的项目,以避免排除潜在用户,但只需使用文本编辑器和 Firefox 即可完成开发和测试。任何现代浏览器都可以读取加载到 Moodle 虚拟学习环境(VLE)中的完整的 MDwiki 项目,这在教育环境中非常有用。 (对于其他 VLE 软件,这可能也是如此,但你应该测试它。)
MDwiki 的默认配色方案并非适用于所有项目,但你可以将其替换为从 Bootswatch.com 下载的其他主题。为此,只需在编辑器中打开 MDwiki HTML 文件,找到 extlib/css/bootstrap-3.0.0.min.css,然后插入下载的 Bootswatch 主题。还有一个 MDwiki gimmick,让用户在浏览器中载入 MDwiki 后,选择 Bootswatch 主题来替换默认值。我经常与有视力障碍的用户一起工作,他们倾向于喜欢高对比度的主题,在深色背景上使用白色文字。
MDwiki 页面使用 Bootswatch Superhero 主题
MDwiki、Markdown 文件和静态图像可以用于许多目的。但是,你有时可能希望包含 JavaScript 幻灯片或反馈表单。Markdown 文件可以包含 HTML 代码,但将 Markdown 与 HTML 混合会让人感到困惑。一种解决方案是在单独的 HTML 文件中创建所需的功能,并将其显示在带有 iframe 标记的 Markdown 文件中。我从 Twine Cookbook 知道了这个想法,它是 Twine 交互式小说引擎的支持站点。Twine Cookbook 实际上并没有使用 MDwiki,但结合 Markdown 和 iframe 标签开辟了广泛的创作可能性。
这是一个例子:
此 HTML 将显示由 Markdown 文件中的 Twine 交互式小说引擎创建的 HTML 页面。
<iframe height="400" src="sugarcube_dungeonmoving_example.html" width="90%"></iframe>
MDwiki 生成的站点结果如下所示:
简而言之,MDwiki 是一个出色的小应用,可以很好地实现其目的。
via: https://opensource.com/article/18/8/markdown-html-publishing
作者: Peter Cheer 选题: lujun9972 译者: geekpi 校对: wxy
本文由 LCTT 原创编译, Linux中国 荣誉推出
*请认真填写需求信息,我们会在24小时内与您取得联系。