├── .gitignore ├── README.md ├── Readme.txt ├── app.js ├── bin └── www ├── model └── post.js ├── package.json ├── public └── stylesheets │ └── style.css ├── routes ├── index.js ├── post.js └── users.js └── views ├── error.ejs ├── head.ejs ├── index.ejs ├── post ├── detail.ejs ├── edit.ejs └── list.ejs └── tail.ejs /.gitignore: -------------------------------------------------------------------------------- 1 | /uploads/ 2 | /node_modules/ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # nodejs-mongoose-blog 2 | 3 | ### 전역모듈 4 | - mongodb, nodemon 5 | 6 | ### setting 7 | npm install 8 | mkdir uploads 9 | chmod 707 uploads/ 10 | npm start 11 | 12 | 13 | ### node_module 14 | - mongodb 15 | - mongoose : DB스키마 정리및 auto incremet 용 ( model 폴더 확인 ) 16 | - mongodb-auto-inrement : unique 키 지정및 auto increament 적용 17 | - multer : 이미지 업로드용 모듈 18 | 19 | ### 라우팅 구조 20 | - post/ => 리스트전체 나열 21 | - post/write => 글작성 22 | - post/detail/:id => 상세글 보기 23 | - post/edit/:id => 글수정 24 | - post/delete/:id => 글삭제 25 | 26 | -------------------------------------------------------------------------------- /Readme.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parkjunyoung/nodejs-mongoose-blog/696c4a73b1f2bbd6f9fce464222b26887f6d27e5/Readme.txt -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var path = require('path'); 3 | var favicon = require('serve-favicon'); 4 | var logger = require('morgan'); 5 | var cookieParser = require('cookie-parser'); 6 | var bodyParser = require('body-parser'); 7 | 8 | var mongoose = require('mongoose'), 9 | autoIncrement = require('mongoose-auto-increment'); 10 | var db = mongoose.connection; 11 | db.on('error', console.error); 12 | db.once('open', function(){ 13 | console.log('Connect mongodb'); 14 | }); 15 | var connection = mongoose.connect('mongodb://localhost/post'); 16 | autoIncrement.initialize(connection); 17 | 18 | 19 | var routes = require('./routes/index'); 20 | var users = require('./routes/users'); 21 | var post = require('./routes/post'); 22 | 23 | var app = express(); 24 | 25 | // view engine setup 26 | app.set('views', path.join(__dirname, 'views')); 27 | app.set('view engine', 'ejs'); 28 | 29 | // uncomment after placing your favicon in /public 30 | //app.use(favicon(path.join(__dirname, 'public', 'favicon.ico'))); 31 | app.use(logger('dev')); 32 | app.use(bodyParser.json()); 33 | app.use(bodyParser.urlencoded({ extended: false })); 34 | app.use(cookieParser()); 35 | app.use(express.static(path.join(__dirname, 'public'))); 36 | app.use('/uploads', express.static('uploads')); 37 | 38 | app.use('/', routes); 39 | app.use('/users', users); 40 | app.use('/post',post); 41 | 42 | 43 | // catch 404 and forward to error handler 44 | app.use(function(req, res, next) { 45 | var err = new Error('Not Found'); 46 | err.status = 404; 47 | next(err); 48 | }); 49 | 50 | // error handlers 51 | 52 | // development error handler 53 | // will print stacktrace 54 | if (app.get('env') === 'development') { 55 | app.use(function(err, req, res, next) { 56 | res.status(err.status || 500); 57 | res.render('error', { 58 | message: err.message, 59 | error: err 60 | }); 61 | }); 62 | } 63 | 64 | // production error handler 65 | // no stacktraces leaked to user 66 | app.use(function(err, req, res, next) { 67 | res.status(err.status || 500); 68 | res.render('error', { 69 | message: err.message, 70 | error: {} 71 | }); 72 | }); 73 | 74 | 75 | module.exports = app; 76 | -------------------------------------------------------------------------------- /bin/www: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | /** 4 | * Module dependencies. 5 | */ 6 | 7 | var app = require('../app'); 8 | var debug = require('debug')('board1:server'); 9 | var http = require('http'); 10 | 11 | /** 12 | * Get port from environment and store in Express. 13 | */ 14 | 15 | var port = normalizePort(process.env.PORT || '3000'); 16 | app.set('port', port); 17 | 18 | /** 19 | * Create HTTP server. 20 | */ 21 | 22 | var server = http.createServer(app); 23 | 24 | /** 25 | * Listen on provided port, on all network interfaces. 26 | */ 27 | 28 | server.listen(port); 29 | server.on('error', onError); 30 | server.on('listening', onListening); 31 | 32 | /** 33 | * Normalize a port into a number, string, or false. 34 | */ 35 | 36 | function normalizePort(val) { 37 | var port = parseInt(val, 10); 38 | 39 | if (isNaN(port)) { 40 | // named pipe 41 | return val; 42 | } 43 | 44 | if (port >= 0) { 45 | // port number 46 | return port; 47 | } 48 | 49 | return false; 50 | } 51 | 52 | /** 53 | * Event listener for HTTP server "error" event. 54 | */ 55 | 56 | function onError(error) { 57 | if (error.syscall !== 'listen') { 58 | throw error; 59 | } 60 | 61 | var bind = typeof port === 'string' 62 | ? 'Pipe ' + port 63 | : 'Port ' + port; 64 | 65 | // handle specific listen errors with friendly messages 66 | switch (error.code) { 67 | case 'EACCES': 68 | console.error(bind + ' requires elevated privileges'); 69 | process.exit(1); 70 | break; 71 | case 'EADDRINUSE': 72 | console.error(bind + ' is already in use'); 73 | process.exit(1); 74 | break; 75 | default: 76 | throw error; 77 | } 78 | } 79 | 80 | /** 81 | * Event listener for HTTP server "listening" event. 82 | */ 83 | 84 | function onListening() { 85 | var addr = server.address(); 86 | var bind = typeof addr === 'string' 87 | ? 'pipe ' + addr 88 | : 'port ' + addr.port; 89 | debug('Listening on ' + bind); 90 | } 91 | -------------------------------------------------------------------------------- /model/post.js: -------------------------------------------------------------------------------- 1 | var mongoose = require('mongoose'); 2 | var Schema = mongoose.Schema; 3 | var autoIncrement = require('mongoose-auto-increment'); 4 | 5 | var PostSchema = new Schema({ 6 | title : String, 7 | content : String, 8 | upload_file : String, 9 | created_at : { type : Date , default : Date.now } 10 | }); 11 | 12 | PostSchema.plugin( autoIncrement.plugin , { model : 'Post' , field : 'id' , startAt : 1 } ); 13 | module.exports = mongoose.model('post' , PostSchema); 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nodejs-mongoose-blog", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "start": "nodemon ./bin/www" 7 | }, 8 | "dependencies": { 9 | "body-parser": "~1.13.2", 10 | "cookie-parser": "~1.3.5", 11 | "debug": "~2.2.0", 12 | "ejs": "~2.3.3", 13 | "express": "~4.13.1", 14 | "mongodb": "^2.1.18", 15 | "mongoose": "^4.5.1", 16 | "mongoose-auto-increment": "^5.0.1", 17 | "morgan": "~1.6.1", 18 | "multer": "^1.1.0", 19 | "serve-favicon": "~2.3.0" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /public/stylesheets/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding: 50px; 3 | font: 14px "Lucida Grande", Helvetica, Arial, sans-serif; 4 | } 5 | 6 | a { 7 | color: #00B7FF; 8 | } 9 | -------------------------------------------------------------------------------- /routes/index.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var router = express.Router(); 3 | 4 | /* GET home page. */ 5 | router.get('/', function(req, res, next) { 6 | res.render('index', { title: 'Express' }); 7 | }); 8 | 9 | module.exports = router; 10 | -------------------------------------------------------------------------------- /routes/post.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var router = express.Router(); 3 | var multer = require('multer'); 4 | var path = require('path'); 5 | var uploadDir = path.join( __dirname , '../uploads' ); 6 | var PostModel = require('../model/post'); 7 | var fs = require('fs'); 8 | 9 | 10 | 11 | router.get('/', function(req, res, next){ 12 | PostModel.find( function(err , post){ 13 | res.render('post/list' , { 'postList' : post }); 14 | }); 15 | }); 16 | 17 | router.get('/detail/:id', (req, res, next) => { 18 | PostModel.findOne( { 'id' : req.params.id } , (err ,post) => { 19 | res.render('post/detail', {'post': post } ); 20 | }); 21 | 22 | }); 23 | 24 | router.get('/write', function(req, res, next){ 25 | var post = []; 26 | res.render('post/edit', { 'post' : post }); 27 | 28 | }); 29 | 30 | router.post( 31 | '/write', 32 | multer({ dest: '/tmp/upload/'}).single('upload_file'), 33 | function(req, res, next){ 34 | 35 | var insert_file_name = (req.file) ? Date.now() + '_' + req.file.originalname : ""; 36 | 37 | var post = new PostModel({ 38 | title : req.body.title, 39 | content : req.body.content, 40 | upload_file : insert_file_name, 41 | }); 42 | 43 | post.save(function(err){ 44 | if(req.file){ //파일이 업로드 일시 45 | var outputPath = uploadDir + '/' + insert_file_name; 46 | fs.rename(req.file.path , outputPath, function (err) { 47 | if (err) { 48 | res.send('err'); 49 | throw err; 50 | }else{ 51 | console.log("file upload success"); 52 | res.redirect("/post"); 53 | } 54 | }); 55 | }else{ //파일업로드가 아닐시 56 | console.log("save success"); 57 | res.redirect("/post"); 58 | } 59 | 60 | }); //post save end 61 | 62 | } 63 | ); 64 | 65 | router.get('/edit/:id', function(req, res, err){ 66 | PostModel.findOne( {id : req.params.id} , function(err, post){ 67 | if(err){ 68 | console.log(err); 69 | }else{ 70 | res.render('post/edit', { 'post' : post } ); 71 | } 72 | 73 | }); 74 | 75 | }); 76 | 77 | router.post('/edit/:id' , multer({ dest: '/tmp/upload/'}).single('upload_file'), function(req, res, err){ 78 | 79 | //먼저 파일검색을 한다. 80 | PostModel.findOne( {id : req.params.id} , function(err, post){ 81 | if(err){ 82 | console.log(err); 83 | }else{ 84 | 85 | //기존 파일업로드가 아닐시 그전 db에서 파일명을 가져온다. 86 | var insert_file_name = (req.file) ? Date.now() + '_' + req.file.originalname : post.upload_file; 87 | 88 | var query = { 89 | title : req.body.title, 90 | content : req.body.content, 91 | upload_file : insert_file_name, 92 | }; 93 | 94 | //업데이트를 한다. 95 | PostModel.update( { id : req.params.id} , { $set : query },function(err){ 96 | 97 | if(err){ 98 | console.log("update fail"); 99 | console.log(err); 100 | }else{ 101 | 102 | if(req.file){ //파일이 업로드 일시 103 | var outputPath = uploadDir + '/' + insert_file_name; 104 | fs.rename(req.file.path , outputPath, function (err) { 105 | if (err) { 106 | res.send('err'); 107 | throw err; 108 | }else{ 109 | console.log("file upload success"); 110 | res.redirect('/post/detail/' + req.params.id ); 111 | } 112 | }); 113 | }else{ //파일업로드가 아닐시 114 | console.log("save success"); 115 | res.redirect('/post/detail/' + req.params.id ); 116 | } 117 | } 118 | }); //post update end 119 | } 120 | }); //post find end 121 | 122 | 123 | }); 124 | 125 | router.get('/delete/:id', function(req, res, err){ 126 | PostModel.remove({id : req.params.id} , function(err){ 127 | if(err){ 128 | console.log(err); 129 | }else{ 130 | res.redirect("/post"); 131 | } 132 | 133 | }); 134 | 135 | }); 136 | 137 | 138 | module.exports = router; 139 | 140 | 141 | 142 | -------------------------------------------------------------------------------- /routes/users.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var router = express.Router(); 3 | 4 | /* GET users listing. */ 5 | router.get('/', function(req, res, next) { 6 | res.send('respond with a resource'); 7 | }); 8 | 9 | module.exports = router; 10 | -------------------------------------------------------------------------------- /views/error.ejs: -------------------------------------------------------------------------------- 1 |
<%= error.stack %>4 | -------------------------------------------------------------------------------- /views/head.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
Welcome to <%= title %>
10 | 11 | 12 | -------------------------------------------------------------------------------- /views/post/detail.ejs: -------------------------------------------------------------------------------- 1 | <% include ../head.ejs %> 2 | 3 |제목 | 5 |작성일 | 6 |
---|---|
<%=post.title%> | 15 |<%= year %>-<%= m %>-<%= d %> | 16 |