on1ystar 머릿속을 정리, 기록하는 곳

Node.js/Express Pug(view engine)-2



의문점이나 지적 등의 관심 및 조언을 위한 댓글이나 메일은 언제나 환영이고 감사합니다.


Pug에서는 파일 내부 구조를 효과적으로 나누고 합칠 수 있도록 다양한 키워드들을 제공해 준다.

views를 만들다 보면 headfooter등과 같은 layout, 또는 필수 script 등은 모든 파일에 들어가야 하므로 코드가 중복되게 되는데 이를 크게 줄이면서, 각 태그의 기능별로 코드를 쪼개어 views 파일들도 모듈화하는 느낌을 줌으로써 추후 유지보수에도 좋고 가독성도 높일 수 있다.

예시를 위한 디렉토리 구조

├──node_modules
├─┬src
│ ├─┬controllers
│ │ ├──userController.js
│ │ └──videoController.js
│ ├─┬routers
│ │ ├──globalRouter.js
│ │ ├──userRouter.js
│ │ └──videoRouter.js
│ └─┬views   <---------------------
│   ├─┬partial
│   │ └──footer.pug
│   ├──base.pug
│   ├──home.pug
│   └──watch.pug
├──server.js
└──pakage.json


☄ Includes



https://pugjs.org/language/includes.html

한 Pug 파일의 내용을 다른 Pug 파일에 삽입할 수 있다.

footer는 거의 모든 파일에 들어가는 태그이며 내용이다. 따라서 이 코드만 따로 파일로 만들어서 include하면 중복도 줄이고 수정할 일이 생길 때 footer.pug만 수정하면 되기 때문에 매우 효율적이다.

// home.pug
doctype html
html(lang="ko")
    head
        title Wetube
    body
        h1 Welcome to Wetube
    include partials/footer.pug
// watch.pug
doctype html
html(lang="ko")
    head
        title Wetube
    body
        h1 Watch video
    include partials/footer.pug
// partials/footer.pug
footer &copy; #{new Date().getFullYear()} Wetube

#{} 문법은 .pug에서 JavaScript 코드를 사용할 수 있게 해준다.

위 코드에서는 현재 년도를 가져와 넣어 준다.


☄ Inheritance: Extends and Block



https://pugjs.org/language/inheritance.html

PugExtendsBlock 키워드로 템플릿 상속을 지원한다.

include를 사용하더라도 중복되는 코드가 많이 발생하고 include 조차 중복해서 작성해 줘야 된다. 그렇다고 모두 개별적으로 .pug파일을 만들어 관리하기도 오히려 더 복잡해 지는 느낌이 있다.

이때 사용하면 좋은 키워드가 ExtendsBlock 키워드다. html은 기본적으로 필수 태그들이 존재하고, 개발자가 원하는 base layout이 존재하기 마련이다. 이를 하나의 파일에 작성하고 Extends 키워드를 이용해 다른 파일들에서 가져다 쓸 수 있다.

단, include와의 차이점은 Extends 의미에서 처럼 단순히 가져다 쓰는 것이 아니라 내부 코드에 Block 키워드를 이용해서 각 파일별로 필요한 코드들을 원하는 위치에 추가하는 식으로 확장할 수 있다.

때문에 다른 .pug 파일을 마치 상속해서 사용하기 때문에 템플릿 상속을 지원한다는 설명이 붙여있다.

// base.pug
doctype html
html(lang="ko")
    head
        block head
    body
        block content
    include partials/footer.pug
// home.pug
extends base.pug

block head
    title home | WeTube

block content
    h1 This is home !

// watch.pug
extends base.pug

block head
    title watch | WeTube

block content
    h1 Watch Video !


☄ Pug 템플릿에서 Variables 사용하기



컨트롤러에서 렌더링 할 .pug 파일에서 사용할 수 있도록 객체(변수)들을 넘겨줄 수 있다.

Response.render(view: string, options?: object, callback?: (err: Error, html: string) => void): void

예를 들어 위 예제에서 title 태그를 보면 타이틀 | WeTube 부분이 중복된다. block head를 다른 파일에서 지우고 base.pug에서 템플릿 변수를 이용해 한 번에 처리할 수 있다.

// videoController.js 일부분
export const trending = (req, res) => res.render("home", { pageTitle: "home" });

위와 같이 res.render의 두 번째 인자에 템플릿에서 사용할 변수를 object로 속성과 값으로 지정해 넘겨 준다.

// base.pug
doctype html
html(lang="ko")
    head
        head #{pageTitle} | WeTube
    body
        block content
    include partials/footer.pug
// home.pug
extends base.pug

block content
    h1 This is home !


Reference

https://nomadcoders.co/wetube

https://pugjs.org/