# Nunjucks - 入門編
- 入門編のこの記事の内容、サンプルコードは [Nunjucks](https://mozilla.github.io/nunjucks/templating.html#raw) に書いてある内容を参考・一部引用し作成している
- テンプレート継承周りの話は別に書く予定なので、この記事では関連するテンプレートタグにも触れていない
- - - -
## Nunjucks とは
- Nunjucks は Python のテンプレートエンジン Jinja2 に影響を受けているテンプレートエンジンで、Mozilla が継続的にメンテナンスをしている
- 記法は EJS に近く、HTML テンプレートに `{% set greeting = "HELLO" %}` のように用意されている独自タグを使うことができる
- EJS よりもテンプレートエンジンとして役にたつ機能が多数用意されているが、記法が JavaScript とも違っている書き方になっているもの多い
- テンプレートエンジンを触ってこなかった人にとってはとっつきにくいと感じる人が多いかもしれない
## シンタックスハイライト
- エディタで作業する場合、デフォルトでシンタックスハイライト対応しているものはほぼなく、プラグインを利用して対応する
- (nunjacks のプラグインがないものはもととなっている `jinja` のシンタックスハイライトを追加すれば対応できるかもしれない)
下記は nunjucks の公式ページ([https://mozilla.github.io/nunjucks/templating.html#syntax-highlighting](https://mozilla.github.io/nunjucks/templating.html#syntax-highlighting))より抜粋。
* atom https://github.com/alohaas/language-nunjucks
* vim https://github.com/niftylettuce/vim-jinja
* brackets https://github.com/axelboc/nunjucks-brackets
* sublime https://github.com/mogga/sublime-nunjucks/blob/master/Nunjucks.tmLanguage
* emacs http://web-mode.org
* vscode https://github.com/ronnidc/vscode-nunjucks
* Webstorm( JetBrains 系 )
* [Twig Support - Plugins](https://plugins.jetbrains.com/plugin/7303-twig-support/) をインストールして 、設定の `File Types` から twig -> `Registered Patterns` に `*.njk` を追加する
## 式と文
- HTML テンプレート中で式や文(テンプレートタグ)を書くことができる
- 式は `{{ username }}` のように中括弧2つで囲うことで展開され、テンプレートタグは `{% set username %}` のように中括弧と `%` で囲うことで実行される
## 変数
### 変数定義の方法
- `set` で定義する
```jinja2
{% set username = "joe" %}
{{ username }} {# username が展開される}
```
- もちろん文字列だけではなく、配列やオブジェクトも定義できる
```jinja2
{% set arr = [1,2,3,4,5] %}
{% set obj = { a: 1, b: 2, c: [0, 1, 2, {d: 3}]} %}
```
- JavaScript のようにプロパティの値にドットや角括弧([]) の記法を使ってアクセスできる
```jinja2
{{ profile.name }}
{{ profile["name"] }}
```
### 値が未定義、 `null` の場合の扱い
- 値が `undefiled` または `null` の場合、何も表示されない
- `undefined` または `null` オブジェクトを参照する場合も同じように何も表示されない
```jinja2
{# profile が未定義だった場合 #}
{{ profile }} {# 何も表示されない #}
{{ profile.firstName }} {{ profile.lastName }} {# 何も表示されない #}
```
## フィルター
- 式のあとに縦棒(`|`)を追加して、 `{{ foo | join(",") }}` のように書くと `foo` の値を `join` という関数へ渡し、その実行結果を表示することができる **フィルター** という機能が使える
- フィルターは自分で用意することもできるが、 Nunjacks がビルトインで便利なフィルターを多数用意してくれている
- そこになければ自作するで良いと思う
- 以下はビルトインで入っているフィルターを使用した例
```jinja2
{# 文字列を整数へ変換する #}
{{ '100' | int }}
{# => 100 #}
{# 改行コードを `
` へ変換する #}
{{ 'こんにちは\n明日は晴れです' | nl2br }}
{# => こんにちは
明日は晴れです #}
{# 配列を引数で渡した値で結合する #}
{{ [0, 1, 2, 3, 4] | join('-') }}
{# => 0-1-2-3-4 #}
{# オブジェクトの値を `JSON.stringify` した結果を表示する #}
{# デバッグしたいときに有用 #}
{% set items = { a: 1, b: [1, 2, 3, c: { d: 123 }] } %}
{{ items | debug }}
{# => {"a":1,"b":[1,2,3,{"c":5}]} #}
{# HTML 文字列(具体的には &, <, >, ‘, ”)をエスケープできる #}
{{ "" | escape }}
{# => <html> #}
{# 特定のキーを基準に配列をまとめ直す #}
{% set items = [
{ name: '田中', type: '赤組' },
{ name: '花澤', type: '白組' },
{ name: '伊藤', type: '赤組' },
{ name: '川田', type: '白組' }
] %}
{% for type, items in items | groupby("type") %}
{{ type }} : {% for item in items %} {{ item.name }} {% endfor %}
{% endfor %} {# =>赤組 : 田中 伊藤
白組 : 花澤 川田
{{value}}
{% endfor %} {# =>1
2
3
#} {# 辞書型のループ #} {% set obj = {a: 1, b: 2, c: 3} %} {% for key, value in obj %}{{key}}, {{value}}
{% endfor %} {# =>a, 1
b, 2
c, 3
#} ``` ### 配列を変数にアンパック ```jinja2 {% for x, y, z in [[0, 1, 2], [3, 4, 5], [6, 7, 8]] %}Point: {{ x }}, {{ y }}, {{ z }}
{% endfor %} {# =>Point: 0, 1, 2
Point: 3, 4, 5
Point: 6, 7, 8
#} ``` - ループの中で `loop` という変数を使える - `loop.index`: ループ中の現在のインデックス値(1から) - `loop.index0`: ループ中の現在のインデックス値(0から) - `loop.revindex`: ループが終わるまでの残り回数(1まで) - `loop.revindex0`: ループが終わるまでの残り回数(1まで) - `loop.first`: 最初の値かどうかを真偽値(boolean)で返す - `loop.last`: 最後の値かどうかを真偽値(boolean)で返す - `loop.length`: アイテムの数 ### 非同期用ループ - カスタムテンプレートローダーを使う場合に使う - `asyncEach`(順序を保持しない), `asyncAll`(順序を保持する) ## 関数っぽいもの - macro - 再利用可能なテンプレートを `macro` というタグで定義できる - `{% macro MacroName %}` ~ `{% endmacro %}` で任意の macro 名を指定し、 テンプレート囲い `macro` を定義する ```jinja2 {% macro field(name, value='', type='text') %}