Editor.md – very rich function Editor, left side edit, right side preview, very convenient, completely free
- Website: pandao. Making. IO/editor/md
- Download website: pandao. Dead simple.. IO/editor/md
Foundation engineering construction
Database design
Article: a list of articles
field | note | |
---|---|---|
id | int | The unique ID of the article |
author | varchar | The author |
title | varchar | The title |
content | longtext | The content of the article |
Build table SQL:
CREATE TABLE 'article' (' id 'int (10) NOT NULL AUTO_INCREMENT COMMENT 'int ', 'author' varchar(50) NOT NULL COMMENT '主 ',' title 'varchar(100) NOT NULL COMMENT' 主 ', 'content' longtext NOT NULL COMMENT '表 示 ', PRIMARY KEY (' id')) ENGINE=InnoDB DEFAULT CHARSET=utf8Copy the code
Foundation project construction
1. Create a SpringBoot project configuration
spring:
datasource:
username: root
password: 123456
#? ServerTimezone =UTC Resolve time zone errors
url: jdbc:mysql://localhost:3306/springboot? serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
driver-class-name: com.mysql.cj.jdbc.Driver
Copy the code
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
Copy the code
2. Entity class
/ / class
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Article implements Serializable {
private int id; // The unique ID of the article
private String author; / / the author name
private String title; / / title
private String content; // The content of the article
}
Copy the code
3. Mapper interface
@Mapper
@Repository
public interface ArticleMapper {
// Query all articles
List<Article> queryArticles(a);
// Add a new article
int addArticle(Article article);
// Query articles based on their id
Article getArticleById(int id);
// Delete articles according to their id
int deleteArticleById(int id);
}
Copy the code
<! DOCTYPEmapper PUBLIC "- / / mybatis.org//DTD Mapper / 3.0 / EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.kuang.mapper.ArticleMapper">
<select id="queryArticles" resultType="Article">
select * from article
</select>
<select id="getArticleById" resultType="Article">
select * from article where id = #{id}
</select>
<insert id="addArticle" parameterType="Article">
insert into article (author,title,content) values (#{author},#{title},#{content});
</insert>
<delete id="deleteArticleById" parameterType="int">
delete from article where id = #{id}
</delete>
</mapper>
Copy the code
Now that you have provided myBatis mapping configuration files, it is natural to tell Spring Boot where these files are located
mybatis:
mapper-locations: classpath:com/kuang/mapper/*.xml
type-aliases-package: com.kuang.pojo
Copy the code
Write a Controller test, ok;
Article editing and Integration (emphasis)
1. Import the editor.md resource and delete unnecessary files
2, Edit the article page editor. HTML, need to introduce jQuery;
<! DOCTYPEhtml>
<html class="x-admin-sm" lang="zh" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Qin jiang '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, the initial - scale = 0.8, the 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">
<! -- Blog Form -->
<form name="mdEditorForm">
<div>Title:<input type="text" name="title">
</div>
<div>The author:<input type="text" name="author">
</div>
<div id="article-content">
<textarea name="content" id="content" style="display:none;"> </textarea>
</div>
</form>
</div>
</div>
</div>
</body>
<! --editormd-->
<script th:src="@{/editormd/lib/jquery.min.js}"></script>
<script th:src="@{/editormd/editormd.js}"></script>
<script type="text/javascript">
var testEditor;
//window.onload = function(){ }
$(function() {
testEditor = editormd("article-content", {
width : "95%"./ / wide
height : 600./ / high
syncScrolling : "single".path : ".. /editormd/lib/".// Load the editor lib path
saveHTMLToTextarea : true.// Save HTML to Textarea
emoji: true.// Enable emoticons
theme: "dark".// Toolbar theme
previewTheme: "dark".// Preview the theme
editorTheme: "pastel-on-dark".// Edit the theme
tex : true.// Enable scientific formula TeX language support, default off
flowChart : true.// Enable flowchart support, disabled by default
sequenceDiagram : true.// Enable sequence/sequence diagram support, default off,
// Image upload
imageUpload : true.imageFormats : ["jpg"."jpeg"."gif"."png"."bmp"."webp"].imageUploadURL : "/article/file/upload".onload : function() {
console.log('onload'.this);
},
/* Specifies the function button to display */
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"]},/* Custom function button, below I customize 2, one is to publish, one is to return to home page */
toolbarIconTexts : {
releaseIcon : " ".index : ",},/* Specifies the callback function */ for the custom button
toolbarHandlers: {releaseIcon : function(cm, icon, cursor, selection) {
// Form submission
mdEditorForm.method = "post";
mdEditorForm.action = "/article/addArticle";// The path to the server
mdEditorForm.submit();
},
index : function(){
window.location.href = '/'; }}}); });</script>
</html>
Copy the code
Write Controller, jump, and save the article
@Controller
@RequestMapping("/article")
public class ArticleController {
@GetMapping("/toEditor")
public String toEditor(a){
return "editor";
}
@PostMapping("/addArticle")
public String addArticle(Article article){
articleMapper.addArticle(article);
return "editor"; }}Copy the code
Image uploading problem
1. Add configuration to front-end JS
// Image upload
imageUpload : true.imageFormats : ["jpg"."jpeg"."gif"."png"."bmp"."webp"].imageUploadURL : "/article/file/upload".// // this is the address to access when uploading pictures
Copy the code
2, the backend request, receive to save the image, need to import the FastJson dependency
// Blog image uploading problem
@RequestMapping("/file/upload")
@ResponseBody
public JSONObject fileUpload(@RequestParam(value = "editormd-image-file", required = true) MultipartFile file, HttpServletRequest request) throws IOException {
// Upload path save Settings
// Get the current SpringBoot project path: system.getProperty ("user.dir")
String path = System.getProperty("user.dir") +"/upload/";
// Sort by month:
Calendar instance = Calendar.getInstance();
String month = (instance.get(Calendar.MONTH) + 1) +"Month";
path = path+month;
File realPath = new File(path);
if(! realPath.exists()){ realPath.mkdir(); }// Upload file address
System.out.println("Upload file save address:"+realPath);
// Solve the file name problem: we use uuid;
String filename = "ks-"+UUID.randomUUID().toString().replaceAll("-"."");
// Write the file directly via CommonsMultipartFile (note this time)
file.transferTo(new File(realPath +"/"+ filename));
// Call back to editorMD
JSONObject res = new JSONObject();
res.put("url"."/upload/"+month+"/"+ filename);
res.put("success".1);
res.put("message"."upload success!");
return res;
}
Copy the code
3, solve the problem of file display, set up virtual directory mapping! In our own extended MvcConfig configuration can be!
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
// Save the file to the real directory /upload/.
PNG file name = 1. PNG file name = 1. PNG file name = 1.
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/upload/**")
.addResourceLocations("file:"+System.getProperty("user.dir") +"/upload/"); }}Copy the code
The Emoji problem
Manually download the emoji package and place it in the picture path:
Modify the editormd.js file
// Emoji graphics files url path
editormd.emoji = {
path : ".. /editormd/plugins/emoji-dialog/emoji/".ext : ".png"
};
Copy the code
The article shows
1. Add methods to Controller
@GetMapping("/{id}")
public String show(@PathVariable("id") int id,Model model){
Article article = articleMapper.getArticleById(id);
model.addAttribute("article",article);
return "article";
}
Copy the code
2. Write the article. HTML page
<! DOCTYPEhtml>
<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>
<! -- Article headers: title, author, last updated date, navigation -->
<h2 style="margin: auto 0" th:text="${article.title}"></h2>The author:<span style="float: left" th:text="${article.author}"></span>
<! -- Text body content -->
<div id="doc-content">
<textarea style="display:none;" placeholder="markdown" th:text="${article.content}"></textarea>
</div>
</div>
<link rel="stylesheet" th:href="@{/editormd/css/editormd.preview.css}" />
<script th:src="@{/editormd/lib/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 () {
testEditor = editormd.markdownToHTML("doc-content", {// Note that this is the id of the DIV above
htmlDecode: "style,script,iframe".emoji: true.taskList: true.tocm: true.tex: true.// No parsing by default
flowChart: true.// No parsing by default
sequenceDiagram: true.// No parsing by default
codeFold: true}); });</script>
</body>
</html>
Copy the code
Restart the project and visit for testing! And you’re done!