Nunjucksって何じゃっくす?

カズキ
仕事と暮らし

Nunjucksというものをご存知でしょうか?
公式サイトを開くと、「A rich and powerful templating language for JavaScript.」とあります。
NunjucksはJavaScriptを埋め込めるタイプのテンプレート言語です。
もし馴染みのある方は「EJS」などをイメージしていただければと思います。

今回の記事では、今注目度の上がっている静的サイト生成ツール「Eleventy」 と、その中で使用できる「Nunjucks」について見てみよう、というテーマでお話したいと思っています。
また、記事のゴールとしては「EleventyのLayout機能を使用して、レイアウトとコンテンツを分離するところまでを実装してみる」という設定で進みたいと思います。
EleventyやNunjucksがどんなものか気になっている、という方のお役に立てれば幸いです。

Eleventyの環境を作る

まずはスタートガイドに沿って、Eleventyを使用するセットアップをしていこうと思います。
以下ではパッケージマネージャとして「npm」を使用し、「Node.js」は12.0以上としています。(Eleventyの記載に合わせています。)

まずは、作業ディレクトリを作り、npm init -y コマンドからスタートします。


    mkdir eleventy-nunjucks
    cd eleventy-nunjucks
    npm init -y
  

次に、Eleventyをインストールします。


    npm install --save-dev @11ty/eleventy
  

インストールできたら、次のコマンドで1度実行してみます。


    npx @11ty/eleventy
  

このような表示がでれば成功です。

最低限のファイルを作成する

ここからはエディタで作業していきます。
VSCodeなどのお好みのエディタで、先ほど作成した「eleventy-nunjucks」を開きます。
現状は以下のように、node_modulesと、package.jsonなどがあるだけかと思います。


    .
    ├── node_modules
    ├── package-lock.json
    └── package.json
  

まずは、プロジェクトルートに「index.njk」を作成します。
ひとまず、以下のように入力してみます。


    <!DOCTYPE html>
    <html lang="ja">
    <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>Eleventy and Nunjucks Test</title>
    </head>
    <body>
      <h1>Eleventy and Nunjucks Test</h1>
      <p>テストです。</p>
    </body>
    </html>
  

そして再度、以下のコマンドで実行してみます。
すると、「_site」ディレクトリが作成され、中に「index.html」が生成されています。


    npx @11ty/eleventy
  

front-matterを使用する

htmlが無事生成されたところで、次にEleventyの「front-matter」という機能を利用して、もう少しテンプレートらしく使用してみようと思います。
「front-matter」とは、Eleventyの機能で、ファイル内で使用するデータを記述できる機能です。
記述形式はデフォルトでは「YAML」形式ですが、「JSON」や「JS」での記述も可能です。以下のように記述します。


    ---
    title: Eleventy and Nunjucks Test
    content: <p>テストです。テストです。テストです。</p>
    ---

    <!DOCTYPE html>
    <html lang="ja">
    <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>Eleventy and Nunjucks Test</title>
    </head>
    <body>
      <h1>Eleventy and Nunjucks Test</h1>
      <p>テストです。</p>
    </body>
    </html>
  

      {# JSONで記述する場合 #}
      ---json
      {
        title: Eleventy and Nunjucks Test,
        content: <p>テストです。テストです。テストです。</p>
      }
      ---
    

そして、これらのNunjucksファイルの中で変数として扱えますので、Nunjucksの変数埋め込み機能(マスタッシュ構文)を利用すると、次のように書くことができます。
※ {{ content | safe }} とありますが、この「safe」はHTMLをエスケープしないという指定です。


    ---
    title: Eleventy and Nunjucks Test
    content: <p>テストです。テストです。テストです。</p>
    ---

    <!DOCTYPE html>
    <html lang="ja">
    <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>Eleventy and Nunjucks Test</title>
    </head>
    <body>
      <h1>Eleventy and Nunjucks Test</h1>
      <p>{{ content | safe }}</p>
    </body>
    </html>
  

再度、以下のコマンドで実行してみます。
変数が展開されて、HTMLファイルに表示されていれば成功です。


    npx @11ty/eleventy
  

Layout機能を使用する

EleventyにはLayoutを設定する機能が存在しています。次はこれを試してみようと思います。
まず、「_includes」ディレクトリを作成します。この名前のディレクトリ内のファイルは直接コンパイルされず、他のテンプレートファイルと組み合わせて使用することが前提です。
ちなみに、今回の記事では触れませんが、設定ファイルを作成してこのディレクトリ名を自由に変更できます。(例えば、「components」など)

ここまでで、以下のような構造になっていると思います。


    .
    ├── _includes
    ├── _site
    ├── index.njk
    ├── node_modules
    ├── package-lock.json
    └── package.json    
  

では、次に「_includes/layouts」ディレクトリを作成し、さらに「_includes/layouts/BaseLayout.njk」を作成します。


    _includes
    └── layouts
        └── BaseLayout.njk 
  

BaseLayout.njk には {{ content | safe }}を記述します。
後でこのレイアウトを使用して「index.njk」を作成しますが、この部分に、ページごとの内容が展開されることになります。


    <!DOCTYPE html>
    <html lang="ja">
    <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>{{ title }}</title>
    </head>
    <body>
      {{ content | safe }}
    </body>
    </html>
  

「index.njk」は次のように変更してみます。
ポイントはfront-matterの「layout: layouts/BaseLayout.njk」の部分です。ここで使用するレイアウトを指定しています。
その他の変更点は、元々「body」タグの中に記述していた部分以外を削除し、変化を確認しやすくするため、少し「p」タグを増やしています。


    ---
    layout: layouts/BaseLayout.njk
    title: Eleventy and Nunjucks Test
    ---
    <h1>Eleventy and Nunjucks Test</h1>
    <p>テストです。</p>
    <p>テストです。</p>
    <p>テストです。</p>
    <p>テストです。</p>
  

コンパイルしてみると、意図した通りに「index.html」が生成されていることがわかります。


    npx @11ty/eleventy
  

    <!DOCTYPE html>
    <html lang="ja">
    <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>Eleventy and Nunjucks Test</title>
    </head>
    <body>
      <h1>Eleventy and Nunjucks Test</h1>
    <p>テストです。</p>
    <p>テストです。</p>
    <p>テストです。</p>
    <p>テストです。</p>
    </body>
    </html>
  

おわりに

以上で、目標だった、「EleventyのLayout機能を使用して、レイアウトとコンテンツを分離するところまでを実装してみる」が達成できました。
他にも、eleventyにはデータをjsonファイルに分離させる機能があったり、Nunjucksには「継承」機能があったりと、多機能かつ使いやすい環境で静的サイトを作ることができそうですね。
さらに、Tailwind CSS や Vite を組み合わせることで、さらに洗練されたテンプレートとして利用できそうだなと感じています。
Eleventyはまだまだ新しいライブラリなので、今後もぜひ、積極的に使っていきたいですね。

カズキ

山口県生まれ、山口県育ち。超インドアなので外出することは少なめですが、Webを身近に感じていただける技術トピックなどを中心にご紹介できればと思っています。よろしくお願いいたします!

Share

Other Blogs

REC.

  1. HOME
  2. BLOG
  3. 仕事と暮らし
  4. Nunjucksって何じゃっくす?

CONTACT US