express에서 nunjucks 템플릿 엔진 사용법에 대해 알아보자.
설치 및 설정
1) 패키지 설치
npm i nunjucks
2) express 기본 구조
const express = require('express');
const nunjucks = require('nunjucks');
const app = express();
app.set('view engine', 'html'); // a
nunjucks.configure('views', { // b
watch: true,
express: app
});
app.get('/', function(req, res) {
// c
res.render('layout', { object });
});
app.listen(8080, () => {
console.log('8080 포트에서 대기중...')
})
a. res.render()시 확장자 디폴트값 설정. c에서 'layout'을 'layout.html'로 변환해준다.
b. nunjucks 설정으로 구문 및 옵션은 더보기란 참조.
// 구문
nunjucks.configure([path], [opts])
path : 렌더링 할때 파일 탐색 시작점
options :
- autoescape (default: true) controls if output with dangerous characters are escaped automatically. See Autoescaping
- throwOnUndefined (default: false) throw errors when outputting a null/undefined value
- trimBlocks (default: false) automatically remove trailing newlines from a block/tag
- lstripBlocks (default: false) automatically remove leading whitespace from a block/tag
- watch (default: false) reload templates when they are changed (server-side). To use watch, make sure optional dependency chokidar is installed.
- noCache (default: false) never use a cache and recompile templates each time (server-side)
- web an object for configuring loading templates in the browser:
- useCache (default: false) will enable cache and templates will never see updates.
- async (default: false) will load templates asynchronously instead of synchronously (requires use of the asynchronous API for rendering).
- express an express app that nunjucks should install to
- tags: (default: see nunjucks syntax) defines the syntax for nunjucks tags. See Customizing Syntax
c. /views/layout.html을 클라이언트에게 보내준다. 이때 object 변수 사용 가능.
// 구문
nunjucks.render(name, [context])
name: 렌더링할 파일
context: 객체 형태로 보내면 렌더링시 변수로 사용 가능하다.
사용법
html과 똑같은데 두 가지 규칙만 기억하고 있으면 된다.
- 변수 사용시: {{ 변수 }} , 괄호 내부에서 +, -, *, /, %, //, ** 연산 가능.
- 연산시: {% 연산 %} , 괄호 내부에서 비교연산, 논리연산(and, or, not) 사용 가능
1. 변수
// app.js
const obj = { name: 'charles', age: 13 }
res.render('layout', { obj, data: 'this is data' });
// /views/layout.html
{{ obj.name }}
{{ obj['age'] }}
{{ data }}
{% set a = 1} // 변수 설정 가능
<br>{{a}}
// output
charles
13
this is data
<br> 1
- 렌더링시 전달받은 데이터는 {{}} 로 사용 가능하다.
- undefined, null은 화면에 렌더링 되지 않는다.
- {% set %} 안에서 변수 설정 가능.
2. 템플릿 상속(extends, super, block)
// app.js
res.render('layout')
<!-- /views/parent.html -->
{% block header %}
This is the default content
{% endblock %}
<section class="left">
{% block left %}{% endblock %}
</section>
<section class="right">
{% block right %}
This is parent content
{% endblock %}
</section>
<!-- /views/layout.html -->
{% extends "parent.html" %}
{% block left %}
This is the left side!
{% endblock %}
{% block right %}
<!-- {{ super() }}-->
This is the right side!
{% endblock %}
<!-- output -->
This is the default content
<section class="left">
This is the left side!
</section>
<section class="right">
<!-- This is parent content : {{super()}} 사용시 -->
This is the right side!
</section>
- {% extends parentTemplate %} 로 상속 받을 수 있다.
- 부모에서 지정한 block 요소는 자식에서 커스터마이징 할 수 있다.
- super() 키워드를 사용하면 부모 block도 사용할 수 있다.
3. if문
// 1.
{% if hungry %}
I am hungry
{% elif tired %}
I am tired
{% else %}
I am good!
{% endif %}
// 2.
{% if happy and hungry %}
I am happy *and* hungry; both are true.
{% endif %}
{% if happy or hungry %}
I am either happy *or* hungry; one or the other is true.
{% endif %}
- if문 자유롭게 사용 가능. 반드시 {% endif %} 으로 끝을 알려줘야 한다.
- and, or 사용 가능
4. for문
1) items가 [객체1, 객체2, ...] 인 경우
// app.js
const items = [{ title: "foo", id: 1 }, { title: "bar", id: 2}];
res.render('layout', { items });
// /views/layout.html
<h1>Posts</h1>
<ul>
{% for item in items %}
<li>{{ item.title }}</li>
{% else %}
<li>This would display if the 'item' collection were empty</li>
{% endfor %}
</ul>
// output
<h1>Posts</h1>
<li>foo</li>
<li>bar</li>
- for문은 파이썬과 유사하다. {% endfor %}로 반드시 끝을 알려야 한다.
- items이 비어있으면 {% else %}로 넘어간다.
2) itmes가 [배열1, 배열2, ...] 인 경우
// app.js
const points = [[0, 1, 2], [5, 6, 7], [12, 13, 14]];
res.render('layout', { points });
// /views/layout.html
<ul>
{% for x, y, z in points %}
<li>Point: {{ x }}, {{ y }}, {{ z }}</li>
{% endfor %}
</ul>
// 이 방법도 가능
<ul>
{% for point in points %}
<li>Point: {{ point[0] }}, {{ point[1] }}, {{ point[2] }}</li>
{% endfor %}
</ul>
// output
<ul>
<li>Point: 0, 1, 2</li>
<li>Point: 5, 6, 7</li>
<li>Point: 12, 13, 14</li>
</ul>
- 두 가지 방법을 기억해놓자
3) items가 객체인 경우
// app.js
const food = {
'ketchup': '5 tbsp',
'mustard': '1 tbsp'
};
res.render('layout', { food });
// /views/layout.html
<ul>
{% for ingredient, amount in food %}
<li>Use {{ amount }} of {{ ingredient }}</li>
{% endfor %}
</ul>
// output
<ul>
<li>Use 5 tbsp of ketchup</li>
<li>Use 1 tbsp of mustard</li>
<li></li>
</ul>
- for (key, value) 형태로 작동한다.
- for문 내부에서 {{ key }}, {{ value }} 꼴로 사용할 수 있다.
5. macro
// app.js
res.render('layout')
// /views/layout.html
{% macro makeList(elem1, elem2='elem2', elem3='elem3') %}
<ul>
<li>{{ elem1 }}</li>
<li>{{ elem2 }}</li>
<li>{{ elem3 }}</li>
</ul>
{% endmacro %}
{{ makeList('this', 'is', 'macro') }}
// output
<ul>
<li>this</li>
<li>is</li>
<li>macro</li>
</ul>
- 함수와 똑같다.
6. include
// app.js
res.render('layout')
<!-- /views/parent.js -->
<div>this is from parent</div>
<!-- /views/layout.js -->
Hi
{% include 'parent.js' %}
<!-- output -->
Hi
<div>this is from parent</div>
- include로 다른 파일을 그대로 가져올 수 있다.
<참조>
https://mozilla.github.io/nunjucks/templating.html
'Node.js + Express' 카테고리의 다른 글
[ Node.js + Express ] JWT (0) | 2022.05.21 |
---|---|
[ Node.js + Express ] 쿠키와 세션으로 초간단 로그인 구현 (0) | 2022.05.20 |
[ Express ] Express 첫 시작, 라우팅과 미들웨어 (0) | 2022.05.12 |
[ Node.js ] 모듈 시스템 (module.exports와 exports) (0) | 2022.05.11 |