EJS 같은 템플레이팅 엔진을 사용하는 이유는 로직을 더하고 데이터를 보충해서 구성하기 위함이다.
쉽게 말하자면 템플레이팅 엔진은 반복이나 조건이 있는 여러 값이 들어가는 HTML의 성능을 올리는 것이 목적이다.
그러기 위해서 EJS 구문을 확실히 익히는 것 또한 중요하다고 할 수 있다.
EJS 구문을 공부하기 전에 VSCode Extension인 EJS language support을 설치하면 EJS 구문을 하이라이팅을 해줘서 기본 HTML 태그와 구분이 쉬워진다.
EJS 공식 문서를 참조하면 Tags라는 것이 있는데 이것은 HTML이 아니니 HTML로 취급하지 말라고 지시하기 위해 사용하는 구문이다.
예를 들면 <%= %>
안에 4 + 5 + 1
인 연산을 넣으면 JavaScript가 연산하듯이 결과값을 출력해준다. 즉 이 구문이 HTML이 아니니 HTML이 아니라 JavaScript의 구문이라고 인식을 하는 것이다.
하지만 템플릿에서 로직을 더하는 것은 좋지 않은 방법이다. 왜냐하면 템플릿은 결과를 출력할 때에 집중하는 것이 더 효율적이기 때문이다.
그래서 템플릿에서 로직을 실행하는 것보다 더 나은 방법으로 결과값을 만든 후 템플릿에게 전달하는 방식을 권장한다.
예를 들자면 현재 localhost:3000/rand
를 요청하면 random.ejs가 렌더링된다.
app.get("/rand", (req, res) => {
res.render("random");
});
random.ejs에는 1 ~ 10까지의 숫자 중 무작위로 렌더링해주는 로직이 작성되어있다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Random</title>
</head>
<body>
<!-- EJS 구문 : 1 ~ 10 사이의 무작위 숫자 렌더링 로직 -->
<h1>Your random number is <%= Math.floor(Math.random() * 10) + 1 %></h1>
</body>
</html>
하지만 템플릿에 로직을 더하는 것을 좋지 않기 때문에 무작위 숫자를 먼저 생성 후 템플릿에 전달하는 방식으로 수정을 하면 된다.
여기서 res.render()
메서드의 두번째 인자에 객체 형식으로 프로퍼티를 작성해주면 이 객체가 첫번째 인자인 템플릿에 전달되게 된다.
app.get("/rand", (req, res) => {
// 먼저 무작위 숫자를 생성하고
const num = Math.floor(Math.random() * 10) + 1;
// render의 두번째 인자로 적용한다.
res.render("random", { num : num });
});
템플릿에서 전달된 객체를 사용할 때는 key
값으로 사용하면 된다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Random</title>
</head>
<body>
<!-- 라우트에서 전달한 두번째 인자로 인해 rand 값을 사용할 수 있음 -->
<h1>Your random number is <%= num %></h1>
</body>
</html>
우선 subreddit.ejs 템플릿을 생성하고 라우팅을 했다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title><%= subreddit %></title>
</head>
<body>
<h1>Browsing The <%= subreddit %> subreddit</h1>
</body>
</html>
app.get("/r/:subreddit", (req, res) => {
const { subreddit } = req.params;
res.render("subreddit", { subreddit });
});
이 방식은 /r/:subreddit
의 요청을 받으면 입력한 매개변수를 req.params
프로퍼티를 이용하여 가져와서 렌더링하는 'subreddit.ejs' 템플릿 파일에 객체형식으로 전달하여 템플릿에 <%=
구문으로 데이터를 전달했다.
이렇게 작성하면 매개변수의 값에 따라 페이지의 title
과 h1
태그의 콘텐츠가 변경될 것이다.
'hello'을 매개변수로 했을 때
'goodbye'를 매개변수로 했을 때
이것을 실제 데이터베이스에서 데이터를 가져와서 사용한다고 하면 아주 유용할 것이다.