minblog是一个不足200行代码的博客系统. 支持管理员登陆, markdown编辑文章
示例地址 : blog.minapp.xin
const fs = require("fs");
const path = require("path");
const Koa = require("koa");
const Router = require("koa-router");
const Render = require("koa-ejs");
const bodyParser = require("koa-bodyparser");
const marked = require("marked");
// 使用koa
const app = new Koa();
const router = new Router();
Render(app, {
root: path.join(__dirname, "view"),
layout: "layout",
viewExt: "ejs"
});
// 管理员登陆密码
let token = "minblog";
// 文章保存在posts.json
let posts = JSON.parse(fs.readFileSync("./posts.json").toString());
//首页
router.get("/", async ctx => {
ctx.state.posts = posts;
await ctx.render("list");
});
//文章页
router.get("/posts/:postid", async ctx => {
ctx.state.post = posts[ctx.params.postid];
ctx.state.postid = ctx.params.postid;
ctx.state.html = marked(ctx.state.post.content);
await ctx.render("detail");
});
//登陆页
router.get("/login", async ctx => {
await ctx.render("login");
});
//登陆接口
router.post("/login", async ctx => {
if (ctx.request.body.token == token) {
ctx.cookies.set("token", token);
ctx.redirect("/");
}
ctx.body = "密码不对";
});
//文章编辑页
router.get("/edit/:postid", async ctx => {
ctx.state.post = posts[ctx.params.postid] || {};
ctx.state.postid = ctx.params.postid;
await ctx.render("edit");
});
//保存文章
router.post("/posts/:postid", async ctx => {
if (!ctx.state.logined) {
ctx.body = "未登录";
}
if (ctx.request.body.show !== "true") {
delete ctx.request.body.show;
}
if (ctx.params.postid == "new") {
posts.push(ctx.request.body);
} else {
posts[ctx.params.postid] = ctx.request.body;
}
fs.writeFileSync("./posts.json", JSON.stringify(posts, null, 2));
ctx.redirect("/posts/" + ctx.params.postid);
});
//上下文加载登陆状态
app.use(async (ctx, next) => {
ctx.state.logined = false;
if (ctx.cookies.get("token") == token) {
ctx.state.logined = true;
}
await next();
});
app.use(bodyParser());
app.use(router.routes()).use(router.allowedMethods());
app.listen(3000);
复制代码
前端页面
//layout.ejs
<!DOCTYPE html>
<html>
<head>
<title>minblog</title>
<style type="text/css">
body{
color:#555;
padding:10px;
padding-top:40px;
max-width: 720px;
margin: 0 auto;
position: relative;
}
a{
color: #001234;
font-weight: bolder;
text-decoration: none;
}
</style>
</head>
<body>
<a href="/" style="position: absolute; top:10px;left: 10px;">minblog</a>
<hr style="border:none; border-top:1px solid #eee" />
<%- body %>
</body>
</html>
//首页部分
<style type="text/css">
.articleList{list-style: none; padding: 0 }
.articleList li{padding-top: 10px; }
.articleList .hide{text-decoration: line-through;}
</style>
<div style="position:absolute;top:10px; right:10px;">
<%if(logined){%>
<a href="edit/new">发表</a>
<%}else{%>
<a href="login">登陆</a>
<%}%>
</div>
<ul class="articleList">
<% for (var i = 0; i < posts.length; i++) {
var postid = posts.length-i-1;
%>
<%if(posts[postid].show || logined){%>
<li class="<%=posts[postid].show?'':'hide'%>" >
<a href="posts/<%=postid%>"><%=posts[postid].title%></a>
</li>
<%}%>
<% } %>
</ul>
//文章页部分
<h1 style="text-align: center"><%=post.title%></h1>
<div><%-html%></div>
<div style="position:absolute;top:10px; right:10px;">
<a href="../edit/<%=postid%>">编辑</a>
</div>
//登陆页部分
<h2>管理员登陆</h2>
<form method="post" action="login">
<input name="token" placeholder="输入登陆密码" />
<button>确定</button>
</form>
//编辑页部分
<form method="post" action="../posts/<%=postid%>" >
<div>
<div>标题</div>
<input style="width: 320px;" type="" name="title" value="<%=post.title%>">
</div>
<br/>
<div>
<div>内容</div>
<textarea name="content" style="width: 480px;" rows="30"><%=post.content%></textarea>
</div>
<div>
<div>可见</div>
<select name="show">
<option value=true <%=post.show?'selected':''%> >显示</option>
<option value=false <%=!post.show?'selected':''%>>隐藏</option>
</select>
</div>
<br/>
<br/>
<button>确定</button>
</form>
复制代码
minblog是一款仅200行代码的轻量级博客系统,支持管理员登录及Markdown编辑文章。该系统采用Koa.js框架搭建,利用EJS模板引擎渲染页面,并通过JSON文件存储文章数据。
6836

被折叠的 条评论
为什么被折叠?



