用NodeJS+Mongodb+Pug开发博客网站
2017-08-27 12:45
232 查看
使用NodeJS,mongodb和pug模板引擎开发个人博客网站,前端样式采用Bootstrap3.0实现,nodejs开发框架采用的是express4.0。
一:开发环境
需要安装node的高级版本,我使用的是node v8.1.2版本:安装mongodb,我安装的是v3.4.5版本:
二:开发介绍
使用express实现工程初始化先新建工程,使用express快速生成工程结构
npm install express-generator -g //全局安装express生成器 express myblog //初始化工程 cd myblog //进入工程目录 npm install //开始安装依赖包 npm start //启动应用
ok,到处为止项目工程初始化完毕,可以打开浏览器输入:http://localhost:3000/ 会打开对应的界面,如下图所示
代表项目初始化成功。
安装对应的依赖包,如mongodb,bootstrap和pug等依赖库。
npm install --save-dev mongodb bootstrap pug
jade替换成pug
完成以上步骤以后我们可以开始正式进入开发了,由于express生成器默认采用的是jade模板引擎,我们需要先切换到pug上来,pug是jade的升级之后的新版本的名称。由于pug是jade的升级版本,所以它们的语法基本是兼容的,所以默认的话我们直接改名字就是了:
如图所示,直接改成pug就行了
文章编辑发送模块开发
OK,完成上述步骤以后我们开始进入最重要的文章编辑发送模块的开发了,毕竟这是一个博客网站,离不开编辑发送功能。富文本编辑器我选择的是UEditor,UEditor官网,大家也可以选择变得编辑器或者像csdn那样使用markdown,也可以自己开发一个富文本编辑器。
新建article_edit.pug,引入ueditor编辑器:
extends layout block content script(type="text/javascript" charset="utf-8" src="/ueditor/ueditor.config.js") script(type="text/javascript" charset="utf-8" src="/ueditor/ueditor.all.js") script(type="text/javascript" charset="utf-8" src="/ueditor/zh-cn.js") .... div(class="container") script(id="editor" type="text/plain" style="width:100%;height:800px;")
完成富文本编辑器的引入,这里要介绍将要使用到的两个获取编辑器内容的方法:
var articleContent = UE.getEditor('editor').getContentTxt();//获取不带标签的内容 var articleContentHTML = UE.getEditor('editor').getContent();//获取带html标签的内容
图片及文件的插入
上传图片需要使用后台的接口,上传成功以后需要返回对应的图片路径,然后通过img标签引入src显示在文本框中,有一点需要特别注意的就是上传图片的返回数据格式,要按下面这样:
{"url":"/uploadfiles/image/20170827/47651877.jpg","state":"SUCCESS"}
否则会认为返回失败,不能正常显示。
上传文件后台接口开发,代码如下所示:
router.post('/ueditors', (req, res, next) => { const action = req.query.action; const date = new Date(); let addPath = "image"; if(action==="uploadvideo"){ addPath = "video"; }else if(action==="uploadfile"){ addPath = "file"; } addPath += "/" + getYYYYMMDD(); const absolutePath = path.resolve(__dirname, '../ueditor/uploadfiles/'+addPath); if(!fs.existsSync(absolutePath)){ fs.mkdirSync(absolutePath); } const form = new multiparty.Form({uploadDir: absolutePath}); form.parse(req, (err, fields, files) => { // var filesTmp = JSON.stringify(files,null,2); if(err){ res.writeHead(500, {'content-type': 'text/plain;charset=utf-8'}); res.end('upload error'); } else { var inputFile = files.upfile[0]; var uploadedPath = inputFile.path; const filename = hashCode(inputFile.originalFilename) + "." + getSuffixStr(inputFile.originalFilename); var dstPath = absolutePath +"/"+ filename; //重命名为真实文件名 fs.rename(uploadedPath, dstPath, function(err) { if(err){ res.writeHead(501, {'content-type': 'text/plain;charset=utf-8'}); res.end('rename error'); } else { res.status(200).json({"url" : "/uploadfiles/" + addPath + "/" + filename, "state":"SUCCESS"}); } }); } }); });
权限及文章管理
在这里我只设置了两个权限一个是管理员,一个是游客,管理员拥有对文章的发布,更新,下架和删除权限,其它人只有光看和评论的权限,所以在user的对象里增加一个role字段,用作权限区分。
新建user数据库表
const insertUserInfo = async (userinfo) => { let isExists = false; await Promise.resolve(findUserNameState(userinfo.username)).then(result => { if(result.status===1002){ isExists = true; } }); if(isExists){ return { status: 1002, message: '注册失败,用户名重复了!'} } await Promise.resolve(findEmailState(userinfo.email)).then(result => { if(result.status===1003){ isExists = true; } }); if(isExists){ return { status: 1003, message: '注册失败,邮箱已被注册!'} } return MongoClient.connect(DB_CONN_STR) .then(db => { return _doInsertUserToDB(db, userinfo); }); } async function _doInsertUserToDB(db, userinfo) { //连接到表 user const collection = db.collection('user'); if(userinfo.username==='superman'){ userinfo.role = 10000; }else{ userinfo.role = 100; } await collection.insert(userinfo); db.close(); return { status: 1000, message: '注册成功!'}; } const findUserNameState = (username) => { return MongoClient.connect(DB_CONN_STR) .then(db => { return _doFindUserNameState(db, username); }); } async function _doFindUserNameState(db, username) { const collection = db.collection('user'); const whereStr = { "username" : username }; let resultDocument; await collection.findOne(whereStr).then(document => { resultDocument = document; }); db.close(); if(resultDocument){ return { status: 1002, message: '用户名重复了!' } } return { status: 1005 }; }
在插入数据之前进行判断,判断用户名是否存在,如果存在则不能重复注册
- 权限控制
/** * [description] 首页用户权限验证,判断用户是否有写文章的权限 * @param {[type]} (req, res, next [description] * @return {[type]} [description] */ router.use((req, res, next) => { if(req.cookies&&req.cookies.username){ const username = req.cookies.username; queryUserInfoByUserName(username).then(document => { let navMenuObj; if(document&&document.role===10000){ navMenuObj = Array.from(NAV_MENU_ARRAY); navMenuObj.push({value: '写文章', path: '/article/publish'}); } if(!navMenuObj){ navMenuObj = NAV_MENU_ARRAY; } req.menu_array = navMenuObj; next(); }); }else{ next(); } }); /* GET home page. */ router.get('/', (req, res, next) => { res.redirect('/index.html'); }); router.get('/index.html', (req, res, next) => { const menu_array = req.menu_array || NAV_MENU_ARRAY; Promise.all([queryArticleCount(), queryAllArticleByCategoryPage(1)]) .then(array => { const totalsize = array[0]; const result = array[1]; res.render('index', optData(menu_array, result.status===1000?result.articleArray:[], 1, totalsize)); }); });
通过cookie判断用户的权限,做到菜单显示的动态控制,只有管理员才有写文章的功能。
评论模块开发
接下来介绍评论模块的开发,首先明确一点,评论是跟着文章走的,我这边没有要求用户一定要登录才可以评论,所以对评论表结构的设计也就简单化了。
新建comments.pug,评论列表
div(class="comments" style="padding: 1em;") if comments h4 评论 (#{comments.length} 条) else h4 评论 - var index = -1; each comment in comments - var date = new Date(comment.time); - index++; div(class='comments-info') div(class='cmnt-icon-left') a(href='#') #[img(src='/images/icon3.png')] div(class='cmnt-icon-right') p #{date.getFullYear()}年#{date.getMonth()+1}月#{date.getDate()}日 #{date.getHours()}:#{date.getMinutes()} p #[a(href='#') #{comment.nickname}] p(class='cmmnt') !{comment.content} div(class='clearfix') div(class='aliqua') a(href='javascript:void(0)' data-index=""+index onclick="blogModel.rebackComment()") 引用
新建comments.pug,发表评论
div(class="consequat" style="padding: 1em;") h4 发表评论 form(onsubmit="return false") input(type="text" id="username" placeholder="请输入您的称呼" required="true" pattern="^\\S{2,}") input(type="email" id="email" placeholder="电子邮箱" required="true") input(type="url" id="subject" placeholder="个人主页" required="true") textarea(type="text" id="content" required="true" placeholder="请填写评论内容") button(class="btn btn-primary" type="submit" id="submitBtn" onclick='blogModel.sendComment()') 发表评论
评论表操作,comment_dao.js
const insertComment = (commentObj) => { return MongoClient.connect(DB_CONN_STR) .then(db => { return _doInsertComment(db, commentObj); }) .catch(error => { return Promise.resolve({status: 1001,message: error.message}); }); } async function _doInsertComment(db, commentObj) { const collection = db.collection("comment"); let insertObj; await collection.insertOne(commentObj).then(result => { insertObj = result; }); db.close(); if(insertObj&&insertObj.insertedCount===1){ return {status: 1000} } return {status:1001, message: 'insert error'}; } const queryCommentByArticleId = (articleId) => { return MongoClient.connect(DB_CONN_STR) .then(db => { return _doQueryCommentByArticleId(db, articleId); }) .catch(error => { return Promise.resolve({status: 1001,message: error.message}); }); } async function _doQueryCommentByArticleId(db, articleId) { const collection = db.collection("comment"); const whereStr = { "articleid" : articleId }; let comments; await collection.find(whereStr).toArray() .then(resultArray => { comments = resultArray; }); db.close(); return {status: 1000, comments }; } module.exports = { insertComment, queryCommentByArticleId }
二:效果展示
登录与注册界面发表文章界面
文章列表界面
文章详情
评论
三:源码下载
下载地址: blog源码下载地址支持源码付费下载,支付完成之后,请发生邮件到269786271@qq.com
相关文章推荐
- Node.js + Express + Mongodb 开发搭建个人网站(二)
- Node.js + Express + Mongodb 开发搭建个人网站(三)
- Node.js + Express + Mongodb 开发搭建个人网站(一)
- Node.js+MongoDB+Express网站开发(一):使用Ping++SDK接入支付功能
- node.js+express+ejs+MongoDB模板修改写《node.js开发指南》中的博客网站实例
- nodeJs+express+mongoDB开发个人博客
- 【我的笔记BLOG1】配置webstorm + node.js +express + mongodb开发博客的环境
- AngularJS + Node.js + MongoDB开发的基于高德地图位置的通讯录
- 用node.js开发 ejs博客项目时遇到的问题
- 基于Node.js平台mongoDB开发——mongoskin(by vczero)
- node.js开发网站直接提交留言到固定邮箱
- 基于 React + NodeJS + Express + MongoDB 开发的一个社区系统
- nodejs + express + ejs + mongodb 一个非常简单的前后端开发的实例
- 全方位的NodeJS+mongodb开发环境搭建
- 使用 Angular.js, Node.js 和 MongoDB开发简单案例
- 使用Nodejs+mongodb开发地图瓦片服务器
- 使用React、Node.js、MongoDB、Socket.IO开发一个角色投票应用的学习过程(一)
- 谈下vue+nodejs+nginx+mongodb的网站部署到服务器
- 利用Sails.js+MongoDB开发博客系统