ejs で json からデータを取り込む
ejs は embeddedjavascript というテンプレートエンジン。
gulp 用のパッケージもあるよ。
HTML に組み込むような書き方なので、デザイナーさんなどと共有しやすいし、学習コストが低くて気に入っています。
外部ファイルの include や 変数の呼び出し、ループなど、はもちろん js で出来ることは(たぶん)全部出来る。
以下、外部ファイルの head を読み込んで、見出しに変数を入れ、配列をループさせる簡単な例です。
<% var title = "見出し1", array=["hoge","fuga","poyo"] %> <html> <head> <% include head %> </head> <body> <h1><%= title %></h1> <ul> <% for(var i=0;i<array.length;i++){ %> <li><%= array[i] %></li> <% } %> </ul> </body> </html>
出力はこんなかんじ
<html> <head> <meta charset="UTF-8"> <meta name="description" content="ejs のサンプルです。" /> <link rel="stylesheet" type="text/css" media="all" href="style.css" /> <title>サンプル</title> </head> <body> <h1>見出し1</h1> <ul> <li>hoge</li> <li>fuga</li> <li>poyo</li> </ul> </body> </html>
include とか出来るだけでも十分っていう場合もあるけど、せっかくなんでデータを取り込んでループさせたりとかしたいですね。
今回私は一週間分の違う料理とその材料を記載したデータを作りましたので、それを gulp + ejs + json でテンプレートに取り込むということをしました。
こんなかんじのイメージです。
ポイントとしては、料理の写真、説明文、材料がユニークな値になり、材料の数も可変ということです。
用意するのは
- gulp
- template.ejs
- data.json
説明を容易にするため、各種ファイルは全て gulp の作業ディレクトリ上にあるということで。
gulpfile.js はこんなかんじ。
var gulp = require('gulp'); var ejs = require('gulp-ejs'); var jsonData = require('./data.json'); gulp.task('build', function(){ return gulp.src('./templates.ejs') .pipe(ejs({ jsonData: jsonData //jsonData に data.json を取り込む })) .pipe(gulp.dest('./')); });
シンプル!json で作ったデータはこんなかんじ。
[ { "daynum": "1", "dishname": "おいしいカレー", "description": "みんな好きなカレーです。甘口です。", "item": [ { "name": "にんじん", "amount": "中3本", }, { "name": "たまねぎ", "amount": "中2玉", }, { "name": "じゃがいも", "amount": "中3個", }, { "name": "カレールー", "amount": "4切れ", } ] }, { ... }, { "daynum": "7", ... } ]
excel データを渡されたりなどした場合、これとかで変換するとラクチンです。
次、 template.ejsはこんなかんじ。
<% var data = jsonData; %> <html> <head> <meta charset="UTF-8"> <link rel="stylesheet" type="text/css" media="all" href="./styles.css" /> <title>一週間の料理</title> </head> <body> <h1>一週間の料理</h1> <% data.forEach(function(day){ %> <section class="dish"> <h2 class="dish__heading"><%= day.daynum %>日目の料理</h2> <div class="dish__image"> <img src="./img/day<%= day.daynum %>.jpg" alt="<%= day.dishname %>"> </div> <div class="dish__body"> <p class="dish__name"><%= day.dishname %></p> <p class="dish__description"><%= day.description %></p> <ul class="ingredients"> <% day.item.forEach(function(item){ %> <li class="ingredients__item"> <p class="ingredients__name"><%= item.name %></p> <p class="ingredients__amount"><%= item.amount %></p> </li> <% }) %> </ul> </div> </section> <% }) %> </body> </html>
ポイントは、 forEach 文で各配列 or オブジェクトを操作する形にするっていうところです。
for(var i=0;data.length;i++){ ... }
のような記法だと、なぜだか data[i].description などが読み込めません…!
出力すると以下のようになるはずです。
<html> <head> <meta charset="UTF-8"> <link rel="stylesheet" type="text/css" media="all" href="./styles.css" /> <title>一週間の料理</title> </head> <body> <h1>一週間の料理</h1> <section class="dish"> <h2 class="dish__heading">1日目の料理</h2> <div class="dish__image"> <img src="./img/day1.jpg" alt="おいしいカレー"> </div> <div class="dish__body"> <p class="dish__name">おいしいカレー</p> <p class="dish__description">みんな好きなカレーです。甘口です。</p> <ul class="ingredients"> <li class="ingredients__item"> <p class="ingredients__name">にんじん</p> <p class="ingredients__amount">中3本</p> </li> <li class="ingredients__item"> <p class="ingredients__name">たまねぎ</p> <p class="ingredients__amount">中2玉</p> </li> <li class="ingredients__item"> <p class="ingredients__name">じゃがいも</p> <p class="ingredients__amount">中3個</p> </li> <li class="ingredients__item"> <p class="ingredients__name">カレールー</p> <p class="ingredients__amount">4切れ</p> </li> </ul> </div> </section> <section class="dish"> <h2 class="dish__heading">2日目の料理</h2> ... </body> </html>
参考記事