template engine
A template engine enables you to use static template files in your application. At runtime, the template engine replaces variables in a template file with actual values, and transforms the template into an HTML file sent to the client. This approach makes it easier to design an HTML page.
템플릿 엔진은 애플리케이션에서 정적 템플릿 파일을 사용할 수 있게 한다. 런타임환경에서 템플릿 엔진은 템플릿 파일의 변수에 값을 채우고 HTML 파일로 변환한 후에 클라이언트로 보낸다. 템플릿 엔진 사용시 HTML 페이지를 더욱 쉽게 디자인 할 수 있다. SSR을 할 때 사용한다.
- 템플릿 엔진의 장점
- HTML page를 쉽게 디자인 할 수 있음
pug
퍼그는 노드JS 환경에서 express와 함께 자주 쓰는 템플릿 엔진이다. 태그가 필요 없는 문법을 사용하기 때문에 정확하고 읽기 편한 템플릿들을 만들 수 있다.
- pug의 특징
- 간결한 문법
- 템플릿 내에서 변수와 표현식 사용가능
- mixins: 템플릿의 컴포넌트로서 재사용 가능
- includes: 템플릿의 일부를 모듈화한 것.
- filters:
pug 설정하기
템플릿들이 모여있는 폴더(views
)로 경로를 설정하고 템플릿 엔진(pug
)를 설정한다.
app.set("views", process.cwd() + "/views");
app.set("view engine", "pug");
pug 설치하기
npm i pug --save
views 디렉토리에서 index.pug
를 생성한다.
html
head
title= title
body
h1= message
index.pug 파일을 렌더링할 수 있도록 라우트를 생성한다. 설정시 view engine 속성을 부여하지 않았다면 확장자까지 같이 써야한다.
app.get("/", (req, res) => {
res.render("index", {title: "hey", message:"hello there"})
});
컴포넌트로 템플릿 생성하기
템플릿의 컴포넌트들을 모듈화하여 새로운 탬플릿을 생성할 수 있다.
partials
컴포넌트들을 보관하는 디렉토리다. partials 디렉토리 안에 footer.pug를 만들어보자.
footer © #{new Date().FullCurrentYear()} | Wetube
view로 사용할 템플릿인 home.pug를 만들어보자. home.pug에서 footer를 따로 구현하기 보다는 partials에서 footer를 include
하자.
doctype html
html(lang="ko")
head
title Wetube
body
h1 Welcome Home!
include partials/footer.pug
inheritance
기본 탬플릿을 토대로 새로운 탬플릿을 생성할 수 있다. base.pug를 만들고 다음과 같이 써보자.
base.pug
doctype html
html(lang="ko")
head
title #{pageTitle} | wetube
body
block content
include partials/footer.pug
템플릿 안에 include
와 block
이 들어 있는거 보인다. include
는 재사용이 가능한 템플릿을 가져오는 키워드다. block
은 base.pug를 사용할 템플릿이 채울 수 있는 공간이다. base.pug를 상속하는 home.pug를 만들어보자.
home.pug
extends base
block content
h1 Welcome Home!
home.pug는 extends
키워드를 통해 base를 상속한다. block content
를 통해 내부에 들어갈 컴포넌트들을 정의한다. 즉, block은 특정 위치를 미리 정해주는 키워드고 상속받은 템플릿은 해당 위치에 필요한 컴포넌트들을 만들 수 있다.
템플릿 안에 변수 넣기
컨트롤러가 템플릿을 렌더링해야만 템플릿이 html 파일로 변환된다. 컨트롤러가 템플릿에 값을 전달해야하는 경우가 있다. 이때 탬플릿에는 #{}
문법을 사용하고 컨트롤러는 객체를 전달함으로써 값을 전달한다.
tempController.js
export const trending = (req, res) => res.render("home", { pageTitle: "Home" });
home.pug
doctype html
html(lang="ko")
head
title #{pageTitle} | wetube
home.pug는 렌더링되면서 컨트롤러부터 객체를 받아 값을 넣는다.
또 다른 방법으로는 컴포넌트 자체에 변수를 부여하는 방법이 있다.
doctype html
html(lang="ko")
head
title=pageTitle
css 적용하기
템플릿 엔진에도 css를 적용할 수 있다. mvp.css
를 사용해보자. 홈페이지에 들어가서 cdn 태그를 가져 온 후에 링크의 속성값으로 넣자. 모든 탬플릿에 적용하기 위해 기본 템플릿인 base.pug
에 설정한다.
doctype html
html(lang="ko")
head
title #{pageTitle} | Wetube
link(rel="stylesheet", href="https://unpkg.com/mvp.css")
body
main
block content
include partials/footer.pug
조건문 적용하기
로그인 상태에 따라 홈페이지의 모습을 바꿀 수 있도록 템플릿을 수정 할 수 있다. 조건문을 통해 템플릿을 만들어보자.
base.pug
doctype html
html(lang="ko")
head
title #{pageTitle} | Wetube
link(rel="stylesheet", href="https://unpkg.com/mvp.css")
body
header
if fakeUser.loggedIn
small Welcome #{fakeUser.name}
nav
ul
if fakeUser.loggedIn
li
a(href="/logout") Logout
else
li
a(href="/login") Login
main
block content
include partials/footer.pug
마찬가지로 템플릿이 값을 사용하기 위해서는 컨트롤러를 통해 객체를 전달해야한다.
controller.js
const fakeUser = {
name: "Ben",
loggedIn: true,
};
const trending = (req, res) =>
res.render("home", { pageTitle: "Home", fakeUser });
반복문 적용하기
탬플릿에게 배열을 전달할 수 있다. each-else
구문을 사용한다. 이터러블 내부에 원소가 없는 경우에는 else문이 실행이 된다.
home.pug
extends base.pug
block content
h2 Welcome here you will see the trending videos
ul
each video in videos
li=video
else
li Nothing is found
mixin 사용하기
mixin이란 값을 입력받을 수 있는 partials이다. pug의 관점에서 함수형 컴포넌트와 유사하다. 리액트의 컴포넌트와의 역할도 비슷한 것 같다. 자바스크립트를 통해 객체를 활용해서 데이터를 받고 각 위치의 변수에 값들을 받아서 로딩한다.
video.pug
mixin video(info)
div
h4=info.title
ul
li Rating: #{info.rating}/5.
li #{info.comments} comments.
li Posted #{info.createdAt}.
li #{info.views} views
mixin
을 사용하려면 다른 pug문서에서 include를 해야한다.
home.pug
extends base.pug
include mixins/video
block content
h2 Welcome here you will see the trending videos
ul
each potato in videos
+video(potato)
else
li Nothing is found
mixin
을 사용할 때 앞에 +
를 붙인다. 예제에서는 +video(인수)
의 형태로 사용했다.