티스토리 뷰

이전에 작성한 회원가입 구현 파일을 그대로 사용하여

게시판 구현도 해보려 한다.

 

우선 구현할 기능은 정말 간단한 게시판이고 로그인된 상태로만 글쓰기가 가능하게 만들것이다.

 

우선 템플릿의 수정과 생성이 필요하다.

 

									//header.pug

    .header__colume
        a(href="/notice") 게시판
       
       
									//mixins/post.pug
 
 mixin post(video = {})
    a(href=`/notice/${video.id}`)=video.title
    if video.description
        p=video.description
       
       
									//notice.pug
 
extends layout/main
include mixins/post

block content
    a(href="/posting") 게시물 작성
    ul
        each posting in postList
            li
                +post({
                    title:posting.title,
                    id:posting._id
                })
 
									//postDetail.pug

extends layout/main
include mixins/post

block content
    h1=postList.title
    p=postList.description

									//posting.pug
                                    
extends layout/main
include mixins/post

block content
    form(action=`/posting`, method="post")
        input(type="text", name="title", placeholder="제목")
        textarea(name="description", placeholder="Description")
        input(type="submit", name="submit")

 

1. 헤더에 게시판으로 갈 수 있는 a 태그를 만들어 줬다.

2. 게시판은 notice.pug 템플릿이다.

3. 게시판에 글은 mixin 으로 post.pug 템플릿을 사용한다.

4. 해당 게시물을 클릭하면 postDetail.pug 가 렌더된다.

5. 게시글 작성은 posting.pug 에 있는 form 을 통해 method post 로 submit 된다.

 

사실 mixin 을 사용해서 post와 postDetail 을 같이 쓸 수 도 있었는데

만들고 나서 생각났다...

 

템플릿은 준비되었으니 라우터를 만들어 본다.

기존에 쓰던 globalRouter 가 있어서 따로 만들려 했지만 또 귀찮아서

그냥 한꺼번에 쓰기로 한다. 이럴꺼면 굳이 왜 이름을 globalRouter로 지었는지..

 

globalRouter.get("/notice", getNotice); //게시판 접근시

globalRouter.get("/postnotice", getPosting); //게시글 작성 화면에 접근시
globalRouter.post("/postnotice", postPosting); //게시글작성 후 submit 되었을시

globalRouter.get("/notice/:id", postDetail); //게시글을 클릭시

 

이제 라우터에 맞는 컨트롤러를 만들어보자.

 

export const getNotice = (req, res) => {};

export const getPosting = (req, res) => {};
export const postPosting = (req, res) => {};

export const postDetail = (req, res) => {};

이렇게 된다.

 

이제 필요한건 mongoose를 이용해 DB에 들어갈 모델을 만들어 준다.

 

//Post.js

import mongoose from "mongoose";

const PostSchema = new mongoose.Schema({
  title: {
    type: String,
    required: "title is required"
  },
  description: {
    type: String,
    required: "description is required"
  },
  createdAt: {
    type: Date,
    default: Date.now
  },
  comments: [
    {
      type: mongoose.Schema.Types.ObjectId,
      ref: "Comment"
    }
  ],
  creator: {
    type: mongoose.Schema.Types.ObjectId,
    ref: "User"
  }
});

const model = mongoose.model("Post", PostSchema);
export default model;

 크게 이렇게 필요할 것 같다. 코멘트를 달 수 있게 만들(예정)것 이고 작성자도 구분할 수 있었으면 좋겠어서

Schema는 이정도 만들었다.

 

모델도 생겼겠다 이제 다시 컨트롤러 작업을 시작해 본다.

 

우선 작성된 게시글이 있을때 게시판에 넘겨주는것부터 시작한다.

export const getNotice = async (req, res) => {
  const postList = await Post.find({});
  res.render("notice", { postList });
};

Post.find 는 Post 안에 있는 모든 정보들을 꺼내줄 것이고 그것을 postList 라는 변수에 담아 게시판 템플릿으로 전달한다. 앞서 템플릿에서는 이미 postList 를 받아서 그릴 준비가 되어있으므로 이름만 맞춰주면된다.

  

이제 게시물 작성부분을 작업해보자.

우선 게시글 작성 템플릿을 렌더해줄 get 을 먼저 만든다

export const getPosting = (req, res) => {
  res.render("postnotice");
};

getPosting 은 그저 게시글 작성 폼을 렌더하는 역할이므로 이게 전부이다.

 

이제 form 에서 submit되었을때 즉 post 되었을때를 작성해준다.

export const postPosting = async (req, res) => {
  const {
    body: { title, description }
  } = req;

  const newPosting = await Post.create({
    title,
    description,
    creator: req.user.id
  });

  res.redirect("/notice");
};

 

이전에 설치했던 미들웨어인 body-parser 에 의하여 submit 되었을시

form 에 입력했던 정보들을 쉽게 조회할 수 있는데

이를 구조분해 할당으로 필요한 정보만 뺀다.

 

이제 mongoDB에 데이터를 만들 수 있게 이전에 작성했던 모델에 양식 맞춰서

Post.create 를 이용하여 작성해 준다.

뭔가 말이 어려운데 그냥 폼에서 넘어온 정보를 미리 지정해놓은 서식에 맞춰서

꾸민다음에 DB에 넘기는것 쯤으로 생각하면 될것같다.

 

이후 res.redirect 를 이용해 게시판 처음화면으로 이동하도록 해준다.

작성한 게시물로 이동하게 하려면

res.redirect(`/notice/${newPosting.id}`);

redirect 부분을 요런식으로 바꿔주기만 하면된다. 쉽다 쉬워

(라우터를 만들때 /notice/:id 로 만들어놨기때문에 해당 게시물의 id가 무엇이든 이렇게 연결되는것)

 

근데 이렇게하고 테스트하면 해당 url에 대한 컨트롤러를 아직 만들지 않았기때문에

무한로딩 혹은 에러가 날것이다.

얼른 만들어 주자

 

export const postDetail = async (req, res) => {
  const {
    params: { id }
  } = req;

  const postList = await Post.findById(id)
  res.render("postDetail", { postList });
};

여기서 params 란 express route parameter를 이용해 추출 할 수 있는 것인데,

앞서 라우터를 말할때 /notice/:id 이것을 예로 들어보면

express 에서 url 에 :id 라고 작성했다면 콜론 뒤에 id 가 key값이 되는 것 이다.

때문에 req.params 를 콘솔에 출력해보면 { "id":"dqwdd12312fqwe" } 이런식으로 출력되어진다.

id 가 아니라도 어느 이름이건 상관없이 작명한대로 불러올 수 있다.

내가 작성한게 key값이 되어지고

실제 그 자리에 들어가는 정보가 value가 되는 것 이다.

 

때문에 실제로는 게시글의 DB id가 그 자리에 들어갈꺼고 그 실제 id 를 가지고

findById 를 통하여 DB내에서 조회하여 찾아내고 그놈을 변수에 담아

템플릿에 전달한다.

 

그럼 아주 쉽게 이런 게시판을 만들 수 있다.

 

이제 미들웨어를 하나 만들고 로그인한 사람만 게시물을 작성 할 수 있게 만들어본다.

 

middleware.js 에 아래처럼 하나 만들어준다.

export const private = (req, res, next) => {
  if (req.user) {
    next();
  } else {
    res.redirect("/");
  }
};

passport 에 의하여 현재 로그인한 사용자의 정보를 어디서든 req.user 로 조회할 수 있기 때문에

가능한 일이다.

이렇게 만약 현재 사용자가 로그인 되어져있다면 다음 작업을 실행하고 아니라면 홈으로

redirect 되도록 만들어주고

globalRouter.get("/posting", private, getPosting);

이렇게 가운대에 꽂아주면 된다.

 

 

다음은 코멘트기능과 스타일링을 좀 해봐야 겠다.

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함