게시글

5만명이 선택한 평균 별점 4.9의 제로초 프로그래밍 강좌! 로드맵만 따라오면 됩니다! 클릭
강좌6 - NodeJS - 8년 전 등록 / 6년 전 수정

익스프레스 템플릿(Jade, Pug), Express template

안녕하세요! 이번 시간에는 익스프레스가 지원하는 템플릿 엔진에 대해 알아보겠습니다! 

템플릿

템플릿은 서식이나 틀을 말하죠. ES2015 강좌를 보신 분들은 문자열 템플릿 때 알아봤었는데요. 익스프레스의 템플릿은 html 템플릿입니다. 제 홈페이지를 보세요. 페이지를 아무리 넘겨도

undefined

이렇게 header와 footer 부분은 반복되죠. (옛날 홈페이지의 디자인입니다. 현재도 반복되는 부분을 찾을 수 있습니다) 이 부분을 모든 html 파일에 계속 넣을건가요? 그리고 만약 header나 footer 중에 하나라도 수정을 해야 한다면 모든 파일을 다 바꿀건가요? 프로그래밍의 핵심은 반복을 최소화하는겁니다. DRY(Don't Repeat Yourself)라고 하는 원칙입니다. 이를 해결하기 위해서 템플릿이 있습니다.

Pug(구 Jade)

가장 유명한 템플릿 중 하나로 Pug가 있습니다. Jade로 더 유명한데요. 이름의 라이센스 문제로 Pug로 강제 개명당했습니다. Ruby 스타일의 간단한 문법이 인상깊은데요. about.htmlmain.html을 Pug로 바꿔보죠. 참고로 Pug로 이름이 바뀌어서 확장자도 jade가 아니라 pug입니다. 또한 pug 특성상 들여쓰기에 주의해야한다는 것을 잊지 마세요! 들여쓸수록 하위 태그가 됩니다. 들여쓰기는 space든 tab이든 상관없지만 하나로 통일해야 하고 항상 일정한 간격으로 들여써야합니다. 2칸이면 2칸, 4칸이면 4칸을 유지해야합니다. 이 참에 header와 footer도 넣어볼까요? 기존 파일을 다음과 같이 수정합니다.

about.html -> about.pug

doctype html
html
  head
    meta(charset='utf-8')
    title About
  body
    header 턴제 게임
    div 제작자: ZeroCho
    footer Copyright ZeroCho. All right reserved.

main.html -> main.pug

doctype html
html
  head
    meta(charset='utf-8')
    title 턴제 게임
  body
    header 턴제 게임
    form#start-screen
      input#name-input(placeholder='영웅 이름을 입력하세요', autofocus)
      button#start 시작
    #screen
      #hero-stat
        span#hero-name
        span#hero-level
        span#hero-hp
        span#hero-xp
        span#hero-att
      form#game-menu(style='display:none;')
        #menu-1 1.모험
        #menu-2 2.휴식
        #menu-3 3.종료
        input#menu-input(name='menuInput')
        button#menu-button 입력
      form#battle-menu(style='display:none;')
        #battle-1 1.공격
        #battle-2 2.회복
        #battle-3 3.종료
        input#battle-input(name='battleInput')
        button#battle-button 입력
      #message
      #monster-stat
        span#monster-name
        span#monster-hp
        span#monster-att
    footer Copyright ZeroCho. All right reserved.
    script(src='turn.js')

pug가 얼마나 간단한지 느낄 겁니다. 잘 보면 about.pugmain.pug에는 공통되는 부분이 있습니다. 바로 새로 넣은 headerfooter죠. 이것을 layout.pug로 빼봅시다.

layout.pug

doctype html
html
  head
    block title
  body
    header 턴제 게임
    block content
    footer Copyright ZeroCho. All right reserved.
    script(src='turn.js')

about.pug

extends ./layout.pug
block title
  title About
block content
  div 제작자: ZeroCho

main.pug

extends ./layout.pug
block title
  title 턴제 게임
block content
  나머지 부분

이렇게 공통되는 부분은 layout으로 빼고 다른 부분만 파일을 다르게하여 관리할 수 있습니다. 특히 about.pugmain.pug 파일에서는 extends 문을 통해 layout을 불러오는 것에 주목해주세요. layout.pug 파일은 block 구문을 통해 미리 다른 파일이 들어올 틀을 마련해두었습니다. 나머지 부분이란 layout.pug와 겹치는 부분을 제외한 나머지 부분을 가리킵니다.

또한 pug는 자바스크립트를 사용해서 반복문이나 조건문을 만들 수도 있습니다. pug에 대해 더 자세하게 알아보고 싶다면 링크를 누르세요. 이제 express에서 pug를 엔진으로 사용해봅시다.

npm install pug --save

server.js

const express = require('express');
const path = require('path');
const app = express();
const route = require('./route.js');
app.set('view engine', 'pug'); // (1)
app.set('views', path.join(__dirname, 'html')); // (2)
app.use(express.static(path.join(__dirname, 'html')));
app.use('/', route);
// 에러 처리 부분
app.listen(8080, () => {
  console.log('Express App on port 8080!');
});

route.js

const express = require('express');
const router = express.Router();
router.get('/', (req, res) => {
  res.render('main'); // (3)
});
router.get('/about', (req, res) => {
  res.render('about'); // (4)
});
module.exports = router;

(1)은 엔진을 pug로 설정하는 부분이고, (2)는 pug 파일들이 있는 폴더를 정하는 부분입니다. (3), (4)에서 res.sendFile 메소드 대신에 res.render로 해당 pug 파일을 전송해줍니다. 아래처럼 header와 footer가 생겼습니다.

undefined

pug 외에도 ejs, mustache 같은 엔진이 더 있습니다. 취향에 따라 사용하세요. 다음 시간에는 DB연결에 대해 알아보겠습니다!

조회수:
0
목록
투표로 게시글에 관해 피드백을 해주시면 게시글 수정 시 반영됩니다. 오류가 있다면 어떤 부분에 오류가 있는지도 알려주세요! 잘못된 정보가 퍼져나가지 않도록 도와주세요.
Copyright 2016- . 무단 전재 및 재배포 금지. 출처 표기 시 인용 가능.
5만명이 선택한 평균 별점 4.9의 제로초 프로그래밍 강좌! 로드맵만 따라오면 됩니다! 클릭

댓글

7개의 댓글이 있습니다.
4년 전
html 을 생성해 주는 팀과 협업을 한다면, 사용하기는 힘든게 맞겠죠? jade 로 만들어 달라고는 할 수 없으니까요
4년 전
nunjucks나 ejs같은 html을 유지하는 템플릿 엔진을 사용하시면 좀 낫습니다.
5년 전
pug에서 #{}와 !{}가 어떻게 다른가요?
5년 전
!는 html을 진짜 html로 표시하고, #은 html을 문자열로 표시합니다.
5년 전
감사합니다!
6년 전
레이아웃으로 나뉘면서부터 블록콘텐츠랑 타이틀.. 뭐가 어떻게 쓰인지 모르겠네요 ㅠ
6년 전
block title끼리 block content끼리 연결된다고 생각하시면 됩니다(그 부분에 쏙 들어갑니다)
6년 전
좋은 강의 감사드립니다! 화이팅!
6년 전
pug가 참... 띄어쓰기나 탭을 겁나 싫어합니다ㅠㅠㅠ 뭘 해도 띄어썻다고 오류 뱉어내네요 ㅎㅎ
7년 전
main.pug 수정요청이요 block content 나머지 부분 --> block content content 나머지 부분
7년 전
node jade템플릿써서 플젝중인데 잘보고있습니다 ㅎㅎ