페이지는 홈의 상단부에 배치된 주요 메뉴이다. 지난 포스팅 3편에서는 관리자 라우팅('/admin/pages')에서 페이지를 관리하는 기능을 구현했다. 이번 포스팅에서는 일반 사용자가 홈에서 볼 수 있는 페이지를 구현해보자.
1 index.js
page데이터는 관리자 뿐 아니라 웹 사이트에 접속하는 모두가 볼 수 있어야 한다. 이를 위해서는 page모델의 데이터를 받아서 어디에서든 접근할 수 있는 app.locals.pages객체가 필요하다. app.locas.pages객체는 전역객체이므로 index.js에 선언한다.
//중략... //Get page Model let Page = require('./models/pageSchema'); //Get all pages to pass to header.ejs Page.find({}).sort({sorting:1}).exec((err, pages)=>{ if(err){ console.log(err); } else{ app.locals.pages = pages; } }); //중략... |
[ index.js]
2 ejs :: header.ejs
관리자 페이지에서 page를 수정하거나 추가할 때마다 메인 화면이 자동으로 바뀌려면, header.ejs의 nav리스트가 조건문에 따라서 랜더링되어야 한다. 이를 위해 header.ejs를 아래와 같이 수정한다.
<!doctype html> <!-- 중략... --> <div id="navbar" class="collapse navbar-collapse"> <ul class="nav navbar-nav"> <% pages.forEach((page)=>{ %> <% if(page.slug == "home"){ %> <li><a href="/"><%= page.title %></a></li> <% }else{ %> <li><a href="/<%= page.slug %>"><%= page.title %></a></li> <% } %> <% }) %> </ul> </div><!--/.nav-collapse --> </div> </nav> <div class="container"> <%- messages('messages', locals) %> |
[ header.ejs ]
3 관리자 페이지 순서변경 구현
현재 아래와 같이 관리자는 관리자 페이지에서 페이지 순서를 마음대로 변경할 수 있으며, 지난 포스팅(2편)에서 구현했다.
관리자가 변경한 페이지의 순서가 관리자 홈 뿐만 아니라 일반 사용자의 홈에서도 변경이 반영되려면, 전역 변수와 콜백의 조합이 필요하다. 아래의 코드는 이를 반영했으며, sortPages함수는 관리자가 변경한 페이지의 순서를 실시간으로 index.js에 있는 req.locas전역 객체에 전달한다.
//중략... //Sort pages functions function sortPages(ids,cb){ let count = 0; for(let i=0; i<ids.length; i++){ let id = ids[i]; count++; ((count)=>{ Page.findById(id, (err,page)=>{ page.sorting = count; page.save((err)=>{ if(err) return console.log(err); ++count; if(count >= ids.length){ cb(); } }) }) })(count); } } //Post reorder pages :: 지난 포스팅 2편에서 구현한 부분을 수정하기 router.post('/reorder-pages', (req, res)=>{ let ids = req.body['id[]']; sortPages(ids, ()=>{ Page.find({}).sort({sorting:1}).exec((err, pages)=>{ if(err){ console.log(err); } else{ req.app.locals.pages = pages; } }); }) }); |
[ admin_pages.js ]
sort({sorting:1})부분은 오름차순으로 정리하라는 의미이며, exec()는 콜백으로 다음 코드를 실행한다. page추가할 때도 변경된 부분이 req.app.locas.pages에 저장되어야 한다.
//Post add page router.post('/add-page', async(req, res)=>{ await check('title', 'title must have a value.').notEmpty().run(req); await check('content', 'Content must have a value.').notEmpty().run(req); let title = req.body.title; let slug = req.body.slug.replace(/\s+/g, '-').toLowerCase(); if(slug == "") slug = title.replace(/\s+/g, '-').toLowerCase(); let content = req.body.content; // 중략... page.save((err)=>{ if(err){ return console.log(err); } Page.find({}).sort({sorting:1}).exec((err, pages)=>{ if(err){ console.log(err); } else{ req.app.locals.pages = pages; } }); req.flash('sucess', 'Page added!'); res.redirect('/admin/pages'); }); } }); } }); |
[ admin_page.js ]
삭제 역시 업데이트가 진행된다.
//Get delete page router.get('/delete-page/:id', (req, res)=>{ Page.findByIdAndRemove(req.params.id, (err)=>{ if(err) return console.log(err); Page.find({}).sort({sorting:1}).exec((err, pages)=>{ if(err){ console.log(err); } else{ req.app.locals.pages = pages; } }); req.flash('success', 'Page Deleted'); res.redirect('/admin/pages/') }) }); |
[ admin_page.js ]
수정도 같은 방식으로 해당 부분을 추가한다.
//Post edit page router.post('/edit-page/:id', async(req, res)=>{ await check('title', 'title must have a value.').notEmpty().run(req); await check('content', 'Content must have a value.').notEmpty().run(req); let title = req.body.title; let slug = req.body.slug.replace(/\s+/g, '-').toLowerCase(); if(slug == "") slug = title.replace(/\s+/g, '-').toLowerCase(); let content = req.body.content; let id = req.params.id; // 중략... Page.findById(id, (err,page)=>{ if(err) return console.log(err); page.title = title; page.slug = slug; page.content = content; page.save((err)=>{ if(err){ return console.log(err); } Page.find({}).sort({sorting:1}).exec((err, pages)=>{ if(err){ console.log(err); } else{ req.app.locals.pages = pages; } }); req.flash('sucess', 'Page added!'); res.redirect('/admin/pages/edit-page/'+ id); }); }) } }); } }); |
[ admin_page.js ]
4 메인 페이지
현재 상단에 위치한 각각의 페이지는 'index.ejs'파일로 모두 랜더링되고 있다. 테스트 중이므로 해당 라우터만 뚫어준다.
let express = require('express'); let router = express.Router(); let Page = require('../models/pageSchema'); \ // Get router.get('/', (req, res)=>{ Page.findOne({slug:'home'}, (err, page)=>{ if(err) console.log(err); res.render('index', { title : page.title, content : page.content }) }) }); // Get a page router.get('/:slug', (req,res)=>{ let slug = req.params.slug; Page.findOne({slug:slug}, (err, page)=>{ if(err) console.log(err); if(!page){ res.redirect('/'); }else{ res.render('index', { title : page.title, content : page.content }) } }) }) //Exports module.exports = router; |
[ pages.js ]
router.get('/:slug') 라우터는 페이지에 따라 해당 .ejs파일을 랜더링한다. 관련 페이지가 있다면 각각 해당되는 .ejs파일을 res.render('index')위치에 넣어준다. 위의 코드에서는 index.ejs로 통일하고, title, content를 다르게 전달하고 있다. index.ejs파일은 아래와 같이 아주 간단하다.
<%- include('./layouts/header.ejs') %> <%- content %> <%- include('./layouts/footer.ejs') %> |
[ index.ejs ]
5 정리
페이지와 마찬가지로 일반 유저를 위한 카테고리가 필요하다. 게스트로 방문한 사용자는 메인 홈에서 자신이 원하는 카테고리를 선택할 수 있어야하며, 이를 위한 구현은 페이지와 같다.(전역객체, app.locals ) 다음 포스팅에서는 전역객체를 이용한 카테고리 접근을 풀어보자.
'웹개발 자료실 > node & Express 쇼핑몰제작Code' 카테고리의 다른 글
페이팔기반, e커머스 플랫폼 제작하기 [7편. 메인 페이지 구현] (0) | 2021.11.08 |
---|---|
페이팔기반, e커머스 플랫폼 제작하기 [6편. 전역객체 카테고리 구현] (0) | 2021.11.08 |
페이팔기반, e커머스 플랫폼 제작하기 [4편. 제품페이지 구현하기] (0) | 2021.11.04 |
페이팔기반, e커머스 플랫폼 제작하기 [3편. 카테고리 CRUD구현] (0) | 2021.11.03 |
페이팔기반, e커머스 플랫폼 제작하기 [2편. 페이지 CRUD 구현] (0) | 2021.10.30 |
댓글