#2.18~#2.25

6mn12j·2020년 9월 7일
1

WeTube

목록 보기
6/12
post-thumbnail

Search Controller

Search form 을 만들기에 앞서서 header.pug 를 변경해줘서 search를 만들어 준다.

action은 routes.search, form태그를 하나 추가한 후 input 태그를 추가한다.method를 get으로 해야 url의 값을 볼 수있다. url을 통해서 보면 search 페이지에 표시할 정보들이 주어진다. android를 검색 한 경우의 url http://localhost:4000/search?term=android

//views/partials/header.pug
.header_column
        form(action=routes.search, method="get")
            input(type="text", placeholder="Search by term...",name="term")

search 한후에는 페이지에 serching by trem(검색한 값)을 보여줄 것이다.
serachingBy 변수를 만들어준다.searchingBy 값을 넘겨주려면 videoController의 search 화면 관련 코드를 수정해준다.

//serach.pug
extends layouts/main

block content
    .search_header  
        h3 Searching for: #{searchingBy}

console.log(req)를 통해서 tearm=android가 req에서 보이는지를 확인해보면.
path ,serach,locals 등 많은 값들이 req를 통해서 전달되는걸 볼 수 있다.그 중 우리가 사용할 값은 req.query에 있는 {term:'android'} 값이다.

export const search = (req, res) => {
    //const searchingaBy = req.query.term;  ES6 이전 
    
 	//ES6
    const {
     query:{ term:searchingBY //term에 이름을 할당 }
     } =req;
     
    //search 템플릿에 변수 전달
	res.render("Search",{pageTitle: "Search",searchingBy}); 
};

searchingBy라는 변수를 사용한다.term대신 사용이 가능하다.
searchingBy를 search템플릿에 전달해 주는 코드를 추가해준다. res.render("Search",{pageTitle: "Search",searchingBy:searchingBy});

코드를 작성한 후 food를 입력한 화면

Join , Log

Join,Login

join과 login을 위한 html 작성(pug로)

action=rotue.login method="post" method가 get이면 정보가 모두 url에 보이게 된다.join과 login 정보는 비밀로 유지해야 하기 때문에 post로 설정해야 한다.
email, password 를 위한 input을 추가한다. input에 name 추가하는 걸 잊지 말것.

//join.pug
extends layouts/main

block content 
    .formcontainer 
        form(action=routes.join, method="post")
            input(type="text", name="name", placeholder="Full Name")
            input(type="email", name="email", placeholder="Email") 
            input(type="password", name="password", placeholder="Password")
            input(type="password", name="password2", placeholder="Verify Password")
            input(type="submit", value="Join Now")
        
 
 //login.pug
 extends layouts/main

block content 
       .form-container 
        form(action=routes.login, method="post")
            input(type="email", name="email", placeholder="Email") 
            input(type="password", name="password", placeholder="Password")
            input(type="submit", value="Log In")
        
        

버튼을 누르면 POST /login POST/join 관련 컨트롤러가 없기 때문에 오류가 난다.

현재는 GET 요청을 보냈을때만 해당하는 컨트롤러가 있다.

//globalRoter.js
import express from "express";
import routes from "../routes";
import { home, search } from "../controllers/videoController";
import { join, login, logout } from "../controllers/userController";

const globalRouter = express.Router();

globalRouter.get(routes.home, home);
globalRouter.get(routes.search, search);
globalRouter.get(routes.join, join);
globalRouter.get(routes.login, login);
globalRouter.get(routes.logout,logout);


export default globalRouter;

get의 요청을 받아오는 처리를 하기위해 getJoin과 postJoin을 만들어준다.라우트,컨트롤러,페이지들은 분리 할 수있다.

/join 경로로 POST 시 작동할 함수를 만든다.
join의 form에 정보를 넣고 join 버튼을 부른다.req.body를 출력해보면 form에서 보네는 정보인{name:"asas",email:"asas@as.com",password:"1234",password2:"1234"}객체가 출력된다. app.js의 bodyParser를 사용하는이유를 알 수 있는데 bodyParser를 삭제하게되면 정보가 출력이 되지 않는다.

postJoin은 form으로 부터 이름 이메일 비밀번호를 가져오고 비밀번호가 갖고,다를때를 처리해주는 함수로 상태코드(status code)를 사용 한다.res.status(400); 상태코드는 웹사이트가 이해할 수있는 코드로 204는 내용이 없다는 뜻, 403은 금지 되었다는 뜻,400은 잘못된 요청이라는 뜻이다.

//postJoin
export const getJoin = (req,res) =>{
    res.render("join", {pageTitle:"Join"});
};

export const postJoin = (req,res) => {
    console.log(req.body);
    
    const{
        body:{  name, email, password, password2}
    } = req;
    if(password !== password2){
        res.status(400);
        res.render("join", {pageTitle:"Join"});
    } else{
        //To Do:Register User(사용자 등록)
        //To Do: Log user in
        res.redirect(routes.home);
    }
    
};
SocialLogin

소셜 계정 로그인 버튼을 만든다. 원하는 소셜 로그인 기능 버튼을 Join화면과 Login화면에 띄울때의 편의성을 위해서 partials 폴더의 socialLogin.pug 파일을만들어서 사용한다.

//socialLogin.pug
.social-login   
    button.social-login--facebook
        span    
            i.fab.fa-github
        |Continue with Githubbutton
    button.social-login--facebook
        span    
            i.fab.fa-facebook
        |Continue with Facebook

|Continue with Githubbutton의 '|' 는 이 안에 들어간 것들을 텍스트로 바꿔준다.'|'없으면 Continue를 elelment로 설정된다. foem container에 추가하기 위해서는 include partials/socialLogin 를 login.pug, join.pug 아래에 추가해준다. partials의 위력을 볼 수있다.

login도 join과 비슷한 작업을 해준다 postLogin과 getLoing 함수를 이용한다.원래는 로그인을 한다면 사용자 비밀번호가 데이터베이스의 비밀번호와 같은지를 검사해줘야 하지만 지금은 일단 로그인에 성공했다면 routes.home으로 redirect 해주는 작업을 만약 에러가 있다면 다시 로그인 화면을 보여준다.

//userController.js
export const postLogin = (req, res) => {
    res.redirect(routes.home);
;}
export const getLogin = (req,res) =>res.render("login", {pageTitle: "Log in"});

로그인 하였을때의 heder도 변경해준다.

//header.pug
 .header_column
        ul
            if !user.isAuthenticated
                li
                    a(href=routes.join) Join
                li
                    a(href=routes.login) LogIn
            else
                li 
                    a(href=`/videos${routes.upload}`) Upload
                li  
                    a(href=routes.userDetail(user.id)) Profile
                li  
                    a(href=routes.logout) Log Out

isAuthenticated 변수를 가짜로 만들어서 사용.사용자정보를 대체한 가짜 데이터 정보를 미들웨어를 통해서 넘겨줘 확인한다.

//middlewares.js
res.locals.user = {
        isAuthenticated: true,
        id: 1
    };
    ```


### Home Controller

전체 애플리케이션의 흐름을 가짜로 한번 넣어본다.
가짜 정보(데이터베이스)를 넣어서 템플릿을 완성한 후 어떤 일이 발생하는지를 확인해 본다.그 후에 데이버테이스를 이용해 실제 정보를 추가하고 사용자 인증 기능도 구현할 수 있을 것이다.


문제점이 한가지 있다. express는 /:id/edit 같은 것을 이해 해서id에 실제 id값 /1/edit가 들어가지만 url은 이해하지 못한다.
어느 하나는 express에 값을 전달하고 어느 하나를 브라우저에 바로 값을 전달하고 있다.요 문제를 해결 해야 한다.

가짜 정보를 이용해서 확인 해본다.


흐름 확인을 위한 db.js
```javascript
export const videos = [
    {
      id: 324393,
      title: "Video awesome",
      description: "This is something I love",
      views: 24,
      videoFile: "https://archive.org/details/BigBuckBunny_124",
      creator: {
        id: 121212,
        name: "Nicolas",
        email: "nico@las.com"
      }
    },
    {
      id: 1212121,
      title: "Video super",
      description: "This is something I love",
      views: 24,
      videoFile: "https://archive.org/details/BigBuckBunny_124",
      creator: {
        id: 121212,
        name: "Nicolas",
        email: "nico@las.com"
      }
    },
    {
      id: 55555,
      title: "Video nice",
      description: "This is something I love",
      views: 24,
      videoFile: "https://archive.org/details/BigBuckBunny_124",
      creator: {
        id: 121212,
        name: "Nicolas",
        email: "nico@las.com"
      }
    },
    {
      id: 11111,
      title: "Video perfect",
      description: "This is something I love",
      views: 24,
      videoFile: "https://archive.org/details/BigBuckBunny_124",
      creator: {
        id: 121212,
        name: "Nicolas",
        email: "nico@las.com"
      }
    }
  ];

home에서 가짜 데이터를 통해서 video들의 목록을 보여주는것이 목표 이다.videoController의 home화면에 videos 배열을 전달 한다.
1.db.js를 export
2.videoController에서 db를 import
3.home.pug에 비디오 목록을 보여줄 코드를 추가

//videoController
import {videos} from "../db"
export const home=(req, res) => {
    res.render("home", {pageTitle: "Home",videos});
};

//home.pug
extends layouts/main

block content 
    .videos 
        each video in videos
            h1=video.title
            //videos 배열에서 하나씩 video를 처리

each ietem in videos 를 통해서 item,혹은 그 변수는 video 배열에서 iteration(반복)각 값을 하나씩 처리한다.

Mixin

다른 곳들에서 사용할 HTML 코드를 만든다.예를 들면 home 페이지에서는 비디오가 한 칸으로 보이겠지만, 누군가의 profile페이지에서도 그 비디오를 볼 수 있어야 한다.
footer를 include해서 재활용하는 것처럼, 비디오 블록 html 코드를 재활용 하기 위해서 html 코드를 만들것이다.
웹사이트에서 계속 반복되는 코드를 복사-붙여넣기 하지 않고 재활용하는 방법으로 이 방법을 mixin 이라고 한다

페이지에 보이는 동영상 목록을 템플릿으로 만들어서 사용 하는 코드. home 화면에 가도 비디오가 보이고 다른 화면에도 import 한다면 다른 화면에서도 비디오를 볼 수 있다.

//mixins/videoBlcok.pug
mixin videoBlock(video = {})
    .videoBlock
        a(href=routes.videoDetail(video.id))
            video.videoBlock__thumbnail(src= video.videoFile, controls=true)
            h4.videoBlcok__title=video.title
            h6.videoBlcok__views=video.views
             
//home.pug
include mixins/videoBlock
block content 
    .videos 
        each item in videos
            +videoBlock({
                id:item.id,
                title:item.title,
                views:item.views,
                videoFile:item.videoFile
            }) 
profile
TIL 쩨끼럽 남기는 중 💻

0개의 댓글