본문 바로가기

페이팔기반, e커머스 플랫폼 제작하기 [6편. 전역객체 카테고리 구현]

by Recstasy 2021. 11. 8.

 

페이지에 이어 일반 사용자도 접근할 수 있는 카테고리 메뉴가 필요하다. 

 

 

 


1 카테고리 생성하기

page와 같은 방식으로 카테고리 데이터를 저장하는 코드를 app.locals전역 객체에 추가한다.

 


  //Get page Model

let Page = require('./models/pageSchema');

  // 중략...


  //Get Category Model
    let Category = require('./models/categorySchema');

  //Get all pages to pass to header.ejs
    Category.find((err, categories)=>{
        if(err){
            console.log(err);
        } else{
            app.locals.categories = categories;
        }
    });
 

[ index.js ]

 

 

 

 

 

 

 


2 View

index.js에서 등록한 categories객체(app.locals.categories)는 뷰에서 사용할 수 있다. 

 


    <div class="container">
    <%- messages('messages', locals) %>
        <div class="row">
            <div class="col-xs-12 col-md-3">
                <h3>Categories</h3>
                <ul class="list-group">
                    <li class="list-group-item"><a href="/products">All products</a></li>
                    <% categories.forEach((c)=>{ %>
                        <li class="list-group-item"><a href="/products/<%=c.slug%>"><%=c.title%>></a></li>
                    <% }) %>
                </ul>
            </div
            <div class="col-xs-12 col-md-1"></div>
            <div class="col-xs-12 col-md-8">

[ header.ejs ]

 

일반 유저가 볼 수 있는 홈의 상단에 카테고리 리스트는 forEach()구문으로 간단하게 표현한다.

header.ejs에서 '<div class="col-xs-12 col-md-8">부분이 본문이며, 해당 부분에 메인 페이지의 콘텐츠가 위치한다. 따라서 </div>부분부터는 'footer.ejs'시작 부분으로 넘긴다. 

 


</div>
</div>
</div>


<br><br><br>
<hr>
<p class="text-center">&COPY; CmsShoppingCart</p>


<script src="https://code.jquery.com/jquery-3.6.0.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" ></script>
<script src="/js/main.js"></script>


</body>
</html>
 

[ footer.ejs ]

 

 

 

 

 

 


3 라우트

관리자가 카테고리를 수정할 때마다 해당 데이터가 메인페이지에 전달되려면, 'admin_categories.js'에서 다음 코드를 추가해야 한다.

 


Category.find((err, categories)=>{
        if(err){
            console.log(err);
        } else{
           req.app.locals.categories = categories;
        }
    });

[ admin_categories.js ]

 

 

 

3-1  Post :: /add-category

관리자가 카테고리를 추가했을 때, 변경된 내용은 index.js의 req.app.locals.categories로 전달된다. 아래 코드에서 기존의 부분과 바뀐 점은 '//카테고리 정보를 header.ejs로 전송'부분이다. 해당 부분만 살펴보자.

 


  //Post add category

    router.post('/add-category', async(req, res)=>{
        await check('title', 'title must have a value.').notEmpty().run(req);

        let title = req.body.title;
        let slug = title.replace(/\s+/g, '-').toLowerCase();

  //validator
        let validatorResults = await validationResult(req);
        if(validatorResults.errors[0] !== undefined){
            res.render('admin/add_category', {
                errors : validatorResults.errors,
                title : title
            });
        }else{
            Category.findOne({slug : slug}, (err, category)=>{
                if(category){
                    req.flash('danger', 'Category title exists, choose another.');
                    res.render('admin/add_category',{
                        title : title
                    });
                }else{
                    var category = new Category({
                        title : title,
                        slug : slug
                    });

                    category.save((err)=>{
                        if(err){
                            return console.log(err);
                        }
               //카테고리 정보를 header.ejs로 전송
                        Category.find((err, categories)=>{
                            if(err){
                                console.log(err);
                            }else{
                                req.app.locals.categories = categories;
                            }
                        });

                        req.flash('sucess', 'Category added!');
                        res.redirect('/admin/categories');
                    });
                }
            });
        }
    });

 

 

 

 

3-2 Post :: /edit-category

edit부분 역시 기존코드에서 '//Get all pages to pass to header.ejs'주석 부분만 변경이 발생했다.(포스팅 3편)

 


  //Post edit page

    router.post('/edit-category/:id', async(req, res)=>{
        await check('title', 'title must have a value.').notEmpty().run(req);

        let title = req.body.title;
        let slug = title.replace(/\s+/g, '-').toLowerCase();
        let id = req.params.id;

  //validator
        let validatorResults = await validationResult(req);
        if(validatorResults.errors[0] !== undefined){
            res.render('admin/edit_category', {
                errors : validatorResults.errors,
                title : title,
                id : id
            });
        }else{

            Category.findOne({slug : slug, _id:{'$ne':id}}, (err, category)=>{
                if(category){
                    req.flash('danger', 'Category title exists, choose another.');
                    res.render('admin/edit_category', {
                        title : title,
                        id : id
                    });
                }else{
                   Category.findById(id, (err,category)=>{
                        if(err) return console.log(err);
                        category.title = title;
                        category.slug = slug;

                        category.save((err)=>{
                            if(err){
                               return console.log(err);
                            }

                           //Get all pages to pass to header.ejs
                            Category.find((err, categories)=>{
                                if(err){
                                    console.log(err);
                                } else{
                                     req.app.locals.categories = categories;
                                }
                            });

                            req.flash('sucess', 'Category edited!');
                            res.redirect('/admin/categories/edit-category/'+id);
                        });
                    })
                }
            });
        }
    });

 

 

 

 

3-3 Get :: /delete-category

'삭제'부분도 기존의 패턴과 같다. 카테고리 삭제 이후 req.app.locals.categories에 갱신된 categories객체를 업데이트 한다. 

 


  //Get delete page

    router.get('/delete-category/:id', (req, res)=>{
        Category.findByIdAndRemove(req.params.id, (err)=>{
            if(err) return console.log(err);

    //Get all pages to pass to header.ejs
            Category.find((err, categories)=>{
                if(err){
                    console.log(err);
                } else{
                   req.app.locals.categories = categories;
                }
            });

            req.flash('success', 'Category Deleted');
            res.redirect('/admin/categories/')
        })
    });

 

 

 

 

 

 

 


4 정리

지금까지 페이지, 카테고리, 제품 파트를 관리자와 사용자 엔티티로 나눠서 구현했다. 이제 남은 부분은 제품의 전체 페이지와 상세 페이지 부분 그리고 장바구니 구현이다.

 

 

 

 

댓글

최신글 전체

이미지
제목
글쓴이
등록일