github地址
使用的是开源的markdown
https://pandao.github.io/editor.md/
首先是文章列表和添加页面
template/article/ArticleList.html
{{template "header.html" .}}
{{template "nav.html" .}}
<!-- 左侧导航和正文内容的分隔线 -->
<div class="splitter"></div>
<!-- 正文内容部分 -->
<div class="pageContent">
<div class="container-fluid">
<h1 class="mt-4" style="font-size: 30px;text-align: center">文章列表</h1>
<div class="card mb-4">
<div class="card-header" style="height: 30px">
<a class=" btn navbar-brand btn-success" href="/article/add">添加文章</a>
</div>
<div class="card-body" style="padding-top: 20px;margin-top: 5px">
<table class="table table-bordered table-hover" id="datatablesSimple">
<thead>
<tr>
<th>ID</th>
<th>文章标题</th>
<th>文章描述</th>
<th>文章分类</th>
<th>文章标签</th>
<th>文章创建者</th>
<th>文章创建时间</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{{range .articleList}}
<tr>
<td>{{.ID}}</td>
<td>{{.Title}}</td>
<td>{{.Desc}}</td>
<td>{{.CateName}}</td>
<td>{{.TagName}}</td>
<td>{{.Username}}</td>
<td>{{.CreatedAt}}</td>
<td><a href="/article/edit?id={{.ID}}">编辑</a>|<a href="/article/delete?id={{.ID}}">删除</a></td>
</tr>
{{end}}
</tbody>
</table>
</div>
</div>
</div>
</div>
{{template "footer.html" .}}
template/article/ArticleAdd.html
{{template "header.html" .}}
{{template "nav.html" .}}
<!-- 左侧导航和正文内容的分隔线 -->
<link rel="stylesheet" href="../../static/md/css/editormd.css"/>
<script src="../../static/md/editormd.min.js"></script>
<div class="splitter"></div>
<!-- 正文内容部分 -->
<div class="pageContent">
<header>
<h3>添加文章 <a href="/article/list">返回列表</a></h3>
</header>
<div class="btns">
<button id="article_add" class="btn btn-success">提交</button>
</div>
<input type="hidden" name="ID" id="id" value="{{.articleRow.ID}}">
<label for="" style="margin-left: 75px;">
标题:<input class="form-control" type="text" name="Title" id="title" value="{{.articleRow.Title}}">
分类:<select class=" form-control cate_select" name="CateId" id="cate_id" >
{{range .cateList}}
<option value="{{.ID}}">{{.CateName}}</option>
{{end}}
</select>
标签:<select class="form-control tag_select" name="TagId" id="tag_id" >
{{range .tagList}}
<option value="{{.ID}}">{{.TagName}}</option>
{{end}}
</select>
</label>
<p style="margin-left: 75px;">
<label for="">
描述:<textarea class="form-control" name="Desc" id="desc" cols="72"
rows="3">{{.articleRow.Desc}}</textarea>
</label>
</p>
<div id="article-editormd" style="height: 100%">
<textarea style="display:none;" name="Content" id="content">{{.articleRow.Content}}</textarea>
</div>
</div>
<script>
$(document).ready(function () {
if({{.article.CateId}} !== ""){
$(".cate_select").val({{.articleRow.CateId}});
}
if({{.article.TagId}} !== ""){
$(".tag_select").val({{.articleRow.TagId}});
}
token = sessionStorage.getItem('token');
if (token === null) {
window.location.href = "/user/login";
}
var testEditor;
testEditor = editormd("article-editormd", {
width: "90%",
height: 640,
syncScrolling: "single",
path: "../../static/md/lib/"
});
$("#article_add").click(function () {
let id = $("#id").val(),
title = $("#title").val(),
cateId = $("#cate_id").val(),
tagId = $("#tag_id").val(),
desc = $("#desc").val(),
content = $("#content").val(),
token = window.sessionStorage.getItem('token'),
userId = window.sessionStorage.getItem('userId'),
username = window.sessionStorage.getItem('username');
data = {Title:title,ID:id,CateId:cateId,TagId:tagId,Desc:desc,Content:content,UserId:userId,Username:username}
console.log(data)
$.ajax({
type: "POST",
dataType: "json",
url: id === "" ? "/article/add" : "/article/edit",
data: data,
beforeSend: function (xhr) {
token = window.sessionStorage.getItem('token');
xhr.setRequestHeader("Authorization", token);
},
success: function (result, status, xhr) {
if (result.code === 200) {
window.location.href = "/article/list";
}
}
})
})
})
</script>
在controller/article.go中写
package controller
import (
"gin-demo/common"
"gin-demo/model"
"gin-demo/response"
"github.com/gin-gonic/gin"
"net/http"
)
func AddArticle(c *gin.Context){
db := common.GetDB()
var reqArticle model.Article
c.Bind(&reqArticle)
title := reqArticle.Title
userId := reqArticle.UserId
cateId := reqArticle.CateId
if title == ""{
response.Response(c,http.StatusUnprocessableEntity,422,"标题不能为空",gin.H{})
return
}
if userId <= 0{
response.Response(c,http.StatusUnprocessableEntity,422,"请登录",gin.H{})
return
}
if cateId <= 0{
response.Response(c,http.StatusUnprocessableEntity,422,"分类不能为空",gin.H{})
return
}
db.Create(&reqArticle)
response.Success(c,gin.H{},"添加成功")
}
func EditArticle(c *gin.Context){
db := common.GetDB()
var reqArticle model.Article
c.Bind(&reqArticle)
title := reqArticle.Title
userId := reqArticle.UserId
cateId := reqArticle.CateId
if title == ""{
response.Response(c,http.StatusUnprocessableEntity,422,"标题不能为空",gin.H{})
return
}
if userId <= 0{
response.Response(c,http.StatusUnprocessableEntity,422,"请登录",gin.H{})
return
}
if cateId <= 0{
response.Response(c,http.StatusUnprocessableEntity,422,"分类不能为空",gin.H{})
return
}
db.Save(&reqArticle)
response.Success(c,gin.H{},"编辑成功")
}
func ArticleListPage(c *gin.Context){
var articleList []model.ArticleCate
var tagRow model.Tag
var cateRow model.Category
db := common.GetDB()
db.Table("articles").Find(&articleList)
for i,v := range articleList{
db.Where("id = ?",v.CateId).First(&cateRow)
db.Where("id = ?",v.TagId).First(&tagRow)
articleList[i].CateName = cateRow.CateName
articleList[i].TagName = tagRow.TagName
}
c.HTML(http.StatusOK,"ArticleList.html",gin.H{"articleList":articleList})
}
func ArticleAddPage(c *gin.Context){
db := common.GetDB();
var cateList []model.Category
var tagList []model.Tag
db.Find(&cateList)
db.Find(&tagList)
c.HTML(http.StatusOK,"ArticleAdd.html",gin.H{"cateList":cateList,"tagList":tagList})
}
func ArticleEditPage(c *gin.Context){
db := common.GetDB()
var id = c.Query("id")
var ArticleRow model.Article
var cateList []model.Category
var tagList []model.Tag
db.Find(&cateList)
db.Find(&tagList)
db.Where("id = ?", id).First(&ArticleRow)
c.HTML(http.StatusOK,"ArticleAdd.html",gin.H{"cateList":cateList,"tagList":tagList,"articleRow":ArticleRow})
}
func ArticleContent(c *gin.Context){
db := common.GetDB()
var id = c.Query("id")
var ArticleRow model.ArticleCate
var cateRow model.Category
db.Table("articles").Where("id = ?", id).First(&ArticleRow)
db.Where("id = ?",ArticleRow.CateId).First(&cateRow)
ArticleRow.CateName = cateRow.CateName
c.HTML(http.StatusOK,"article.html",gin.H{"articleRow":ArticleRow})
}
在router/router.go路由中添加
package router
import (
"gin-demo/controller"
"gin-demo/middleware"
"github.com/gin-gonic/gin"
)
func InitRouter(r *gin.Engine) *gin.Engine {
r.LoadHTMLGlob("template/**/*")
//加载静态资源
r.Static("/static", "./static")
r.Static("/md", "./static/md")
//首页页面
r.POST("/getUserInfo", controller.GetUserInfo)
r.GET("/index", controller.IndexPage)
//注册
r.POST("/user/register", controller.Register)
r.GET("/user/register", controller.RegisterPage)
//登录
r.POST("/user/login", controller.Login)
r.GET("/user/login", controller.LoginPage)
r.GET("/user/logout", controller.Logout)
//分类页面
r.GET("/cate/list", controller.CategoryListPage)
r.GET("/cate/add", controller.CategoryAddPage)
r.GET("/cate/edit", controller.CategoryEditPage)
r.GET("/cate/delete", controller.DeleteCate)
r.POST("/cate/add", middleware.JwtAuthMiddleware(), controller.AddCate)
r.POST("/cate/edit", controller.EditCate)
//标签页面
r.GET("/tag/list", controller.TagListPage)
r.GET("/tag/add", controller.TagAddPage)
r.GET("/tag/edit", controller.TagEditPage)
r.GET("/tag/delete", controller.DeleteTag)
r.POST("/tag/add", middleware.JwtAuthMiddleware(), controller.AddTag)
r.POST("/tag/edit", controller.EditTag)
r.GET("/article/list", controller.ArticleListPage)
r.GET("/article/add", controller.ArticleAddPage)
r.GET("/article/edit", controller.ArticleEditPage)
r.POST("/article/add", middleware.JwtAuthMiddleware(), controller.AddArticle)
r.POST("/article/edit", middleware.JwtAuthMiddleware(), controller.EditArticle)
r.GET("/article",controller.ArticleContent)
return r
}
首页展示
在template/index 下创建indexHead.html、indexFoot.html
indexHead.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>首页</title>
<link rel="stylesheet" href="../../static/css/bootstrap.min.css">
<script src="../../static/js/jquery.min.js"></script>
<script src="../../static/js/bootstrap.min.js"></script>
</head>
<style>
.navbar>.container .logo {
line-height: 40px;
font-weight: 500;
}
.navbar>.container .logo a {
color: #161209;
font-family: "YaHei Consolas Hybrid", Consolas, "Meiryo UI", "Malgun Gothic", "Segoe UI", "Trebuchet MS", Helvetica, monospace, monospace;
}
.navbar-default {
background-color: #fff;
}
.navbar-nav>li>a {
line-height: 60px;
font-size: 16px;
padding-top: 0;
padding-bottom: 0px;
}
</style>
<body>
<header>
<nav class="navbar navbar-default" id="navbar">
<div class="container">
<div class="navbar-header" style="margin-right: 40px;padding-right: 40px;height: 60px">
<h1 class="logo" >
<a href="/index">XX博客</a>
</h1>
</div>
<div class="collapse navbar-collapse" id="header-navbar">
<!-- <form class="navbar-form nav navbar-form navbar-right search-nav" action="/" method="GET">-->
<!-- <div class="input-group">-->
<!-- <input type="text" name="keyword" class="form-control" placeholder="请输入关键字" maxlength="20"-->
<!-- autocomplete="off">-->
<!-- <span class="input-group-btn">-->
<!-- <button type="submit" class="btn btn-default btn-search">搜索</button>-->
<!-- </span>-->
<!-- </div>-->
<!-- </form>-->
<ul class="nav navbar-nav navbar-left ">
<li><a href="/index">首页</a></li>
</ul>
</div>
</div>
</nav>
</header>
indexFoot.html
<div class="footer">
<div class="container">
<p>Copyright © 2021.convee All rights reserved</p>
</div>
</div>
</body>
</html>
index.html
{{template "indexHead.html" .}}
<div class="container">
<div class="content-wrap">
<div class="content center">
<div class="title">
<div class="more">
{{range .cateList}}
<a href="/?cate_id={{.ID}}" class="btn btn-success">{{.CateName}}</a>
{{end}}
</div>
</div>
{{if .articleList}}
{{range .articleList}}
<div class="excerpt">
<header>
<a class="cat btn-warning" href="#" >{{.CateName}}<i></i></a>
<h2><a href="/article?id={{.ID}}" class="btn btn-info">{{.Title}}</a></h2>
</header>
{{.Desc}}
<p class="meta">
<a class="category btn btn-default" href="#"><i class="glyphicon glyphicon-folder-open"></i> {{.CateName}}</a>
<a class="time btn btn-default" href="#"><i class="glyphicon glyphicon-time"></i> {{.UpdatedAt.Format "2006-01-02 15:04:05"}}</a>
</p>
</div>
{{end}}
{{else}}
<div class="text-center">
<h3>
<stong>暂无内容</stong>
</h3>
</div>
{{end}}
</div>
</div>
</div>
{{template "indexFoot.html" .}}
点击标题显示内容 article.html:
{{template "indexHead.html" .}}
<link rel="stylesheet" href="../../static/md/css/editormd.css"/>
<script src="../../static/js/jquery.min.js"></script>
<script src="../../static/js/bootstrap.min.js"></script>
<script src="../../static/md/lib/marked.min.js"></script>
<script src="../../static/md/lib/prettify.min.js"></script>
<script src="../../static/md/lib/raphael.min.js"></script>
<script src="../../static/md/lib/underscore.min.js"></script>
<script src="../../static/md/lib/sequence-diagram.min.js"></script>
<script src="../../static/md/lib/flowchart.min.js"></script>
<script src="../../static/md/lib/jquery.flowchart.min.js"></script>
<script src="../../static/md/editormd.min.js"></script>
<div class="container">
<div class="content-wrap">
<div class="content">
<header class="article-header">
<h1 class="article-title"><a href="" >{{.articleRow.Title}}</a></h1>
<div class="article-meta ">
<span class="item category"><a href="#">{{.articleRow.CateName}}</a></span>
<span class="item category"><a href="#">{{.articleRow.TagName}}</a></span>
<span class="item time ">{{.articleRow.UpdatedAt.Format "2006-01-02 15:04:05"}}</span>
</div>
</header>
<article class="article-content">
<div id="test-editormd-view2">
<textarea id="article_content">{{.articleRow.Content}}</textarea>
</div>
</article>
</div>
</div>
</div>
<script type="text/javascript">
$(document).ready(function () {
testEditormdView2 = editormd.markdownToHTML("test-editormd-view2", {
htmlDecode: "style,script,iframe",
emoji: true,
taskList: true,
tex: true, // 默认不解析
flowChart: true, // 默认不解析
sequenceDiagram: true, // 默认不解析
});
})
</script>
{{template "indexFoot.html" .}}
然后效果如下,其实做的很垃圾,哈啊哈哈哈。实在是技术不行 555555555555555555555
添加页面