예전에 gulp html tag include를 포스팅한 적이 있다.
최근에는gulp-nunjucks-render 플로그인을 알게 되어 포스팅을 해보려고 한다.

설치하기

$ npm install --save-dev gulp-nunjucks-render

task 만들기:

var nunjucksRender = require('gulp-nunjucks-render');

다음으로, Nunjuck을 쉽게 사용할 수 있는 프로젝트 구조를 만들어야 한다.
아래의 구조로 사용할 예정이다:

project/
  |- app/
      |- index.html and other .html files
      |- pages/
      |- templates/
          |- partials/

templates 폴더는 모든 Nunjucks 부분 및 다른 Nunjucks 파일을 pages폴더에 추가하는 데 사용된다.
pages 폴더는 HTML로 컴파일 할 파일을 저장하는 데 사용된다. 일단 컴파일되면 app폴더에 만들어진다.

layout.nunjucks라는 파일을 만들어 templates 폴더에 저장한다. <html>, <head><body> 태그와 같은 상용구 코드가 있어야 한다.
또한, CSS 및 JavaScript 파일에 대한 링크와 같이 모든 페이지에서 유사한 내용을 포함 할 수 있다.

다음은 layout.nunjucks 파일의 예이다.

<!-- layout.nunjucks -->

<!DOCTYPE html>
<html lang="ko">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <link rel="stylesheet" href="css/styles.css">
</head>
<body>

  <!-- 이 콘텐츠 블록에 대한 코드를 다른 파일에 작성한다. -->
  {% block content %} {% endblock %}

  <script src="jquery/dist/jquery.js"></script>
  <script src="js/main.js"></script>
</body>
</html>

추천하는 방식은 Nunjucks 파일과 부분 파일에 .nunjucks 확장자를 사용하는 것을 좋다.
왜냐하면 Nunjucks를 실행하고 있다는 것을 알고 있기 때문이다.
.nunjucks가 마음에 들지 않으면 파일을 .html로 사용해도 상관없다.

다음으로, pages 디렉토리에 index.nunjucks 파일을 생성 해보자. 이 파일은 결국 index.html로 변환되어 app폴더에 저장된다.

layouts.nunjucks를 확장하여 layout.nunjucks에 정의 된 상용구 코드를 포함해야한다.

<!-- index.nunjucks -->
{% extends "layout.nunjucks" %}

그런 다음 {% block content %}{% endblock %} 사이에 index.nunjucks에 특정한 HTML 코드를 추가 할 수 있다.

<!-- index.nunjucks -->
{% extends "layout.nunjucks" %}

{% block content %}
<h1>안녕?! 여긴 index page 입니다.</h1>
{% endblock %}

Nunjucks 파일 설정이 끝났다. 이제 index.nunjucksindex.html에 덮는 nunjucks작업을 만들어 보자.

gulp.task('nunjucks', function() {
  // 여기에 nunjucks 요소를 넣는다.
});

nunjucks-render를 사용하면 경로 옵션을 사용하여 템플릿 경로를 지정할 수 있다.

gulp.task('nunjucks', function() {
  // 페이지에서 .html 이나 .nunjucks 파일 가져오기
  return gulp.src('app/pages/**/*.+(html|nunjucks)')
  // nunjucks와 템플릿을 렌더링
  .pipe(nunjucksRender({
      path: ['app/templates']
    }))
  // app folder에 출력
  .pipe(gulp.dest('app'))
});

이제 명령 줄에서 gulp nunjucks를 실행 해보자.
Gulp는 index.html 파일을 만들어 app 폴더에 저장했다.

index.html 파일을 열면 다음 코드가 표시된다.

<!DOCTYPE html>
<html lang="ko">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <link rel="stylesheet" href="css/styles.css">
</head>
<body>

  <h1>안녕?! 여긴 index page 입니다.</h1>

  <script src="js/main.js"></script>
</body>
</html>

<h1> 태그를 제외한 모든 것이 layouts.nunjucks에서 나온 것이다.
<head> 태그를 사용하거나 JavaScript를 추가하거나 CSS 파일을 변경해야한다면 layouts.nunjucks에서 할 수 있다는 것을 알면 그에 따라 모든 단일 페이지가 업데이트된다.

Nunjucks 네비게이션 추가하기

index.nunjucks에 추가하기 전에 부분을 만들어야한다. navigation.nunjucks라는 부분을 만들어서 templates 폴더에있는 partials 폴더에 저장해 봅시다.

그런 다음이 부분에 간단한 메뉴를 추가해 보자.

<!-- navigation.nunjucks -->
<nav>
  <a href="#">Home</a>
  <a href="#">About</a>
  <a href="#">Contact</a>
</nav>

이제 네비게이션을 index.nunjucks파일에 추가 해보자. Nunjucks가 제공하는 {% include "경로 - 부분"%} 문장의 도움으로 부분을 추가 할 수 있다.

{% block content %}

<h1>안녕?! 여긴 index page 입니다.</h1>
<!-- navigation 부분을 추가-->
{% include "partials/navigation.nunjucks" %}

{% endblock %}

gulp nunjucks를 실행하면 이제 다음 코드로 index.html 파일을 가져온다.

네비게이션과 같은 아이템 사용할 때 우리는 페이지에 있을 때 링크 중 하나에 Class를 추가해야하는 상황에 종종있다.
다음은 그 예이다.

<nav>
  <!-- active 클래스는  해당 페이지에만 존재 해야한다. -->
  <a href="#" class="active">Home</a>
  <a href="#">About</a>
  <a href="#">Contact</a>
</nav>

active 클래스는 해당 페이지에 있는 경우에만 페이지 링크에 존재 해야한다.
about 페이지에 있는 경우 active 클래스는 about 링크에만 있어야 한다.

Nunjucks 매크로 추가하기

먼저 templates 폴더에 있는 macros폴더에 nav-macro.nunjucks파일을 만든다. (nav-macro를 사용하여 두 개의 네비게이션 nunjuck 파일을 혼동하지 않도록 한다.)

nav-macro.nunjucks파일을 만들면 매크로를 작성할 수 있다. 모든 매크로는 다음 태그로 시작하고 끝난다.

{% macro functionName() %}
  <!-- 여기에 매크로 요소를 넣는다. -->
{% endmacro %}

active라는 매크로를 만들자. 네비게이션에 active클래스를 출력하는 것이 목적이다. activePage라는 하나의 인수를 취해야 하는데, 기본값은 'home'이다.

{% macro active(activePage='home') %}
  <!-- 여기에 매크로 요소를 넣는다. -->
{% endmacro %}

매크로 내에 작성 될 HTML을 작성한다. 여기서 Nunjucks가 제공하는 if 함수를 사용하여 active 클래스를 추가해야하는지 확인할 수도 있다.

{% macro active(activePage='home') %}
<nav>
  <a href="#" class="{%if activePage == 'home' %} active {% endif %}">Home</a>
  <!-- about 과 contact 메뉴에도 반복시킨다. -->
</nav>
{% endmacro %}

매크로 작성이 끝났다. index.nunjucks에서 사용하는 법을 알아보자.

Nunjucks의 import함수를 사용하여 매크로 파일을 추가한다. (이전에 부분을 추가 할 때 include함수를 사용했다.) 매크로 파일을 가져올 때 변수로 설정해야한다. 다음은 그 예이다.

<!-- index.nunjucks -->
{% block content %}

<!-- Importing Nunjucks Macro -->
{% import 'macros/nav-macro.nunjucks' as nav %}

{% endblock %}

이 경우 nav 변수를 전체 navigation.nunjucks 매크로 파일로 설정했다. 그런 다음 nav 변수를 사용하여 파일에 기록 된 모든 매크로를 호출 할 수 있다.

{% import 'macros/navigation.nunjucks' as nav %}
<!-- Creating the navigation with activePage = 'home' -->
{{nav.active('home')}}

이 변경으로 gulp nunjucks를 다시 실행하면 다음과 같이 출력되는 것을 볼 수 있다.

<nav>
  <a href="#" class=" active ">Home</a>
  <a href="#" class="">About</a>
  <a href="#" class="">Contact</a>
</nav>

Nunjucks의 템플릿 경험을 향상시키기 위해 할 수있는 일이 한 가지 더 있다. HTML로 데이터를 채우는 것이다.

데이터로 HTML 완성하기

데이터가 포함 된 data.json이라는 파일을 만들어 보자. 이 data.jsonapp폴더에 두는 것이 좋다.

이제 데이터를 추가해 보겠다. 이전의 예제 데이터를 사용할 수 있다.

{
  "images": [
    {
      "src": "image-one.png",
      "alt": "Image one alt text"
    }, {
      "src": "image-two.png",
      "alt": "Image two alt text"
    }
  ]
}

그런 다음이 data.json 파일의 데이터를 사용하려면 nunjucks 작업을 약간 조정해야 한다. data.json가 제대로 실행되게 하려면 다른 gulp 플러그인의 도움을 받아야하는데 그 플러그인은 gulp-data 이다.

gulp-data를 설치해보자.

$ npm install --save-dev gulp-data

var data = require('gulp-data');

Gulp-data는 파일을 반환 할 수 있는 함수를 사용한다. Node가 제공하는 require 함수를 사용하여 이 data 파일을 얻을 수 있다.

.pipe(data(function() {
  return require('./app/data.json')
}))

require를 사용하여 node_modules가 아닌 사용자 정의 디렉토리에서 파일을 가져올 때 Node에 디렉토리 경로를 알려줘야한다. 여기서는 Node가 현재 디렉토리로 시작하도록 지시 한 ./에서 시작하여 data.json 파일을 찾는다.

gulp-data를 nunjucks 작업에 추가한다.

gulp.task('nunjucks', function() {
  return gulp.src('app/pages/**/*.+(html|nunjucks)')
    // Adding data to Nunjucks
    .pipe(data(function() {
      return require('./app/data.json')
    }))
    .pipe(nunjucksRender({
      path: ['app/templates']
    }))
    .pipe(gulp.dest('app'))
});

마지막으로 추가 된 데이터를 사용하도록 index.nunjucks에 마크업을 추가해 보겠다.

<!-- index.nunjucks -->
{% block content %}
<div class="gallery">
  <!-- Loops through "images" array -->
  {% for image in images %}
  <div class="gallery__item">
    <img src="{{image.src}}" alt="{{image.alt}}">
  </div>
  {% endfor %}
</div>
{% endblock %}
<!-- index.html -->
<div class="gallery">
  // 이제 `gulp nunjucks`를 실행하면,
  // 다음 마크업과 함께 `index.html` 파일을 얻어야 한다.
  <div class="gallery__item">
    <img src="image-one.png" alt="Image one alt text">
  </div>

  <div class="gallery__item">
    <img src="image-two.png" alt="Image two alt text">
  </div>
</div>

수고하셨습니다.

마치며

저도 혼자 공부하느라고 이정도 알지만 실무에서는 좀 더 다양하게 응용해서 사용할 수 있을거 같습니다. 좋은 팁들 있으면 알려주시면 감사하겠습니다. 그리고 다른 html include 플러그인보다는 낫다고 봅니다.

참고 블로그 https://zellwk.com/blog/nunjucks-with-gulp/