티스토리 뷰

web : back-end/node js

[node js] Express: Pug 템플릿 엔진

무니웜테일패드풋프롱스 2020. 6. 18. 22:31

PUG 템플릿 엔진이란?

Express에서 지원하는 템플릿 엔진으로서, html코드를 매우 간결화 시킨 문법을 가진다. pug으로 작성된 코드는 컴파일 되어 html로 렌더링 하는 형식으로 매우 생산성이 높고, 재사용성이 높다. 

왜 템플릿 엔진을 쓰는가?

이를 위해서는 템플릿 엔진이 어떻게 작동하는지를 알아야 한다.

템플릿 엔진은 외부 소스로부터 데이터 혹은 소스코드를 받아서 컴파일링하고, 그것을 HTML문서로 렌더링한다. 

따라서, 정적(static)페이지를 재사용 할 수 있게 해주고, 데이터 베이스나 다른 소스코드로부터 데이터를 받아오고 컴파일링 함으로써 동적(dynamic) 페이지를 만들 수 있게 해준다. 

 

그러면 Pug 템플릿 엔진을 어떻게 사용하는지 알아보자.

 

먼저 아래와 같이 pug을 깔아준다. 

npm install --save pug

 

메인 소스코드에 아래와 같이 app.set을 추가해준다.

app.set('view engine', 'pug'); //express에게, 동적 템플릿을 pug으로 컴파일 하라고 알려주고 
app.set('views', 'views'); //어디에 template이 있는지 알려주는 것. 즉 views파일에 있다고 알려줌 

여기서 app.set( 'view engine', 'pug')은 컴파일할 템플릿 엔진을 알려준다. 우리는 pug을 사용할 것이므로 pug을 써준다

app.set('views', 'views')는 템플릿이 어디있는지 정의해준다. 나는 views 파일에 pug 소스코드를 저장해놓았으므로, views라고 정의해주었다.

 

 

res.render() 를 이용해 html 파일 send하는 대신, pug 파일을 render한다. 

router.get('/',(req,res,next)=>{
   // res.sendFile(path.join(rootDir,'views','shop.html'));
   res.render('shop');
});

여기서 해당 pug 파일의 파일명 외에는 추가해줄 것이 없다. 앞에서 app.set 을통해 pug 이 default template engine 으로 설정되었고, views 위치를 설정해줌으로써 해당 템플릿이 어디에 있는지 설정했기 때문이다. 

 

pug 파일에 데이터 포워딩해서, 동적 화면 만들어주기

const adminData = require('./admin');
// admin파일로부터 받은 데이터 
router.get('/',(req,res,next)=>{
   
    const products = adminData.products; //특정 데이터 저장 
   res.render('shop', {prods:products, docTitle:"Shop"});
});

 

이렇게 보내고자 하는 데이터를 key: value 쌍으로 묶어서 렌더하면 해당 pug 파일에 우리가 넣은 데이터가 포워딩 되고,

  title #{docTitle}

pug 파일에서는 이런 형태로 받아온 데이터의 key값을 통해  띄울 수 있다.

 

Pug 템플릿 엔진으로 layout 만들기

 

먼저, html소스코드에서 공통된 부분을 pug문법으로 바꾸어, main-layout.pug에 작성한다.

 

각각의 페이지는 해당 main layout을 사용하기 위해서 extends 파일의 위치를 맨 처음에 선언해줘야한다.

extends layouts/main-layout.pug

 

각 페이지마다 달라지는 CSS link나 main 코드는 pug에서 지원하는 'block'을 이용해주면 된다.

CSS를 예시로 들었을 때, main-layout.pug에서는 아래와 같이 block을 정의를 해주고 

    head
        meta(charset="UTF-8")
        meta(name="viewport", content="width=device-width, initial-scale=1.0")
        title #{pageTitle}
        link(rel="stylesheet", href="/css/main.css")
        block style

 

각 페이지에서는 아래와 같이 'block 이름' 아래에다가 선언을 해주면 된다.

extends layouts/main-layout.pug
block style
    link(rel="stylesheet", href="/css/product.css")
    link(rel="stylesheet", href="/css/form.css")

 

main 역시 마찬가지로 아래와 같이 메인 레이아웃에서 block content로 처리하고 각 페이지마다 block content 아래에 각자의 main 코드를 작성하면 된다.

<!DOCTYPE html>
html(lang="en")
    head
        meta(charset="UTF-8")
        meta(name="viewport", content="width=device-width, initial-scale=1.0")
        title #{pageTitle}
        link(rel="stylesheet", href="/css/main.css")
        block style
    body
        header.main-header
            nav.mian-header__nav
                ul.main-header__item-list
                    li.main-header__item
                        a(href="/", class=(path==='/'?'active':'')) Shop
                    li.main-header__item
                        a(href="/admin/add-product", class=(path ==='/admin/add-product' ? 'active': '')) Add Product
    block content

 

extends layouts/main-layout.pug

block style
    link(rel="stylesheet", href="/css/product.css")
    link(rel="stylesheet", href="/css/form.css")
block content
    main
        form.product-form(action="/admin/add-product", method="POST")
            .form-control
                labe(for="title") Title
                input(type="text", name="title")#title
            button.btn(type="submit") Add product

 

또, 각 페이지마다 해당 페이지에 active 되게 하는 기능은 js 파일의 render() 로부터 해당 객체를 넘겨 받은 후 비교해서 처리하면 된다.

 

먼저 아래와 같이 라우트를 처리하는 js파일에서 path 이름을 render 인자로 넘겨준다.

router.get('/add-product',(req,res,next)=>{
    res.render('admin',{
        pageTitle:'Add Product :)', 
        path:'/admin/add-product',
    }); 
});

 class를 선언한 후, 현재 path의 value에 따라 active를 달리 해준다. 

li.main-header__item
          a(href="/", class=(path==='/'?'active':'')) Shop
li.main-header__item
          a(href="/admin/add-product", class=(path ==='/admin/add-product' ? 'active': '')) Add Product

 

참조:https://www.sitepoint.com/a-beginners-guide-to-pug/#:~:text=Pug%20is%20a%20template%20engine,from%20a%20database%20or%20API.

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함