この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
今回はCUIツールのGruntのプラグインgrunt-contrib-jstを使ったjsテンプレートを管理する機会があたので一連の流れをご紹介します。
アジェンダ
- JavaScript Templates(JST)とは?
- Grunt-contrib-jstを使ってみる
JavaScript Templates(JST)とは?
テンプレート部分とデータ部分を関連づけて表示するイメージです。以下の記事がイメージしやすくとても参考になりました。
参考記事:JavaScriptテンプレートエンジンJsRender 基本のキ
それではJSTを用いて実際に表示してみたいと思います。今回はサンプルとして、Underscore.jsのテンプレートAPIを使って表示してみます。
使用したライブラリ
- jquery.js
- underscore.js
- backbone.js
- bootstrap.js
- bootstrap.css
テンプレート
scriptタグ内にhtmlタグがマークアップしています。これがjsテンプレートになります。
<%= %>はテンプレート内に変数を埋め込む表記です。
<script type="text/template" id="uiListItemTemplate">
<li class="item well">
<span class="name">Name : <%= name %></span><br />
<span class="age">Age : <%= age %></span>
</li>
</script>
モデルを作成
データを管理するしてくれるモデルを作成します。
var itemModel = Backbone.Model.extend({
defaults: {
name : 'Test User',
age : 20
}
});
ビューを作成
今回は簡単な表示用のViewを作成します。8行目でunderscore.jsのメソッド_.template()でjsテンプレートとモデルが結合しています。
var listView = Backbone.View.extend({
el : '#uiLists',
template : $('#uiListItemTemplate').html(),
initialize: function(options) {
this.render();
},
render: function() {
var element = _.template( this.template , this.model.attributes );
this.$el.append(element);
}
});
表示する
モデル:itemModelをインスタンス化して、ビュー:listViewをインスタンス化する際に渡して表示します。
(function(){
var item = new itemModel;
var lists = new listView({ model: item });
}());
ソースコード表示
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>JST Sample</title>
<link rel="stylesheet" href="assets/css/lib/bootstrap.css">
<style type="text/css">#uiLists{margin-top: 20px; padding-right: 20px;}#uiLists li{list-style: none;}</style>
</head>
<body>
<ul id="uiLists"></ul>
<script type="text/template" id="uiListItemTemplate">
<li class="item well">
<span class="name">Name : <%= name %></span><br />
<span class="age">Age : <%= age %></span>
</li>
</script>
<script type="text/javascript" src="assets/js/lib/underscore.js"></script>
<script type="text/javascript" src="assets/js/lib/jquery.js"></script>
<script type="text/javascript" src="assets/js/lib/bootstrap.js"></script>
<script type="text/javascript" src="assets/js/lib/backbone.js"></script>
<script type="text/javascript">
var itemModel = Backbone.Model.extend({
defaults: {
name : 'Test User',
age : 20
}
});
var listView = Backbone.View.extend({
el : '#uiLists',
template : $('#uiListItemTemplate').html(),
initialize: function(options) {
this.render();
},
render: function() {
var element = _.template( this.template , this.model.attributes );
this.$el.append(element);
}
});
(function(){
var item = new itemModel;
var lists = new listView({ model: item });
}());
</script>
</body>
</html>
表示するためでしたので結構はしょってしまっていますが、実際にJSテンプレートを使ってレンダリングしてみました。
今回は1つのページに1テンプレートでしたが、開発する際はJSテンプレート数が増えてきて管理も大変になってきます。
その問題を解決してくれるのがしてくれるのがビルドツールのGruntさんのプラグインgrunt-contrib-jstです。
Grunt-contrib-jstを使ってみる
grunt-contrib-jstは指定したフォルダ内のhtmlファイル(テンプレート)を、1つのUnderscore.jsのテンプレート用jsファイルに変換してくれます。
類似プラグインにHandlebarsテンプレート用のgrunt-contrib-handlebarsもあります。
package.json
それでは早速つかってみたいと思います。まず作業用フォルダを作成し、package.jsonを作成します。
今回使用するGruntプラグインを記載します。
- grunt-contrib-watch
- grunt-contrib-jst
{
"author": "Takashi Kiyota",
"name": "grunt contrib jst Test",
"version": "0.9.1",
"devDependencies": {
"grunt": "",
"grunt-contrib-watch" : "",
"grunt-contrib-jst" : ""
}
}
Nodeパッケージをインストール
プラグインのインストールしてみます、コンソール画面から作業ファイルまで移動し以下のコマンドを入力します。
cd xxx/xxx/xxxx/作業フォルダ
npm install
Gruntfile.jsの作成
プラグインのインストールが出来たら、Gruntfile.jsを作成します。
gruntに指定したフォルダ内にjsテンプレート用のhtmlを作成します。監視フォルダと出力ファイルはGruntfile.js(26行目)で指定ができます。今回は以下の指定をしています。
- 監視フォルダ
- [assets/templates/]
- 出力ファイル
- [assets/js/jst/template.js]
module.exports = function (grunt) {
'use strict';
grunt.initConfig({
watch: {
jst: {
files: ['assets/templates/**/*.html'],
tasks: ['jst:dev']
}
},
jst: {
options: {
processName: function (filename) {
return filename.match(/templates\/(.+)\.html$/)[1];
},
processContent: function (src) {
return src.replace(/(^\s+|\s+$)/gm, '');
},
amd: true
},
dev: {
files: {
'assets/js/jst/template.js': ['assets/templates/**/*.html']
}
}
}
});
grunt.registerTask('default', ['watch']);
grunt.registerTask('build', ['jst']);
};
jsテンプレート変換用htmlを作成
[assets/templates/]内にsample.htmlを作成します。テンプレート側で表示する際は、htmlのファイル名を指定して表示することになります。(今回はsampleになります。)
注意点として、scriptタグに囲まずにそのまま記述します。
<li class="item well">
<span class="name">Name : <%= name %></span><br />
<span class="age">Age : <%= age %></span>
</li>
テンプレート出力
実際にテンプレートを出力してみます。コンソール画面に移動し作業フォルダのトップ階層に移動し、
以下コマンドを入力します。
grunt build
template.js
[assets/js/jst/]内にtemplate.jsがされていれば成功です。中身をみると先ほど作成したsample.html内の中身がテンプレート用に変換されています。
this["JST"] = this["JST"] || {};
this["JST"]["sample"] = function(obj) {
obj || (obj = {});
var __t, __p = '', __e = _.escape;
with (obj) {
__p += '<li class="item well">\n<span class="name">Name : ' +
((__t = ( name )) == null ? '' : __t) +
'</span><br />\n<span class="age">Age : ' +
((__t = ( age )) == null ? '' : __t) +
'</span>\n</li>';
}
return __p
};
変換されたテンプレートファイルで表示する
1.template.jsを読み込む
Grunt-contrib-jstで変換されたテンプレートを読み込みます。
<script type="text/javascript" src="assets/js/jst/template.js"></script>
2.ビュー(View)の編集
3行目の箇所でcontrib-jst作成されたオブジェクトJST[]にテンプレート用htmlの名前を指定します。
今回はsample.htmlだったので、JST['sample']になります。
8行目のthis.template()の引数にモデルが保持しているデータを渡しています。
var listView = Backbone.View.extend({
el : '#uiLists',
template : JST['sample'],
initialize: function(options) {
this.render();
},
render: function() {
var element = this.template(this.model.attributes);
this.$el.append(element);
}
});
ソースコード
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>JST Sample</title>
<link rel="stylesheet" href="assets/css/lib/bootstrap.css">
<style type="text/css">#uiLists{margin-top: 20px; padding-right: 20px;}#uiLists li{list-style: none;}</style>
</head>
<body>
<ul id="uiLists"></ul>
<script type="text/javascript" src="assets/js/lib/underscore.js"></script>
<script type="text/javascript" src="assets/js/lib/jquery.js"></script>
<script type="text/javascript" src="assets/js/lib/bootstrap.js"></script>
<script type="text/javascript" src="assets/js/lib/backbone.js"></script>
<script type="text/javascript" src="assets/js/jst/template.js"></script>
<script type="text/javascript">
var itemModel = Backbone.Model.extend({
defaults: {
name : 'Test User',
age : 20
}
});
var listView = Backbone.View.extend({
el : '#uiLists',
template : JST['sample'],
initialize: function(options) {
this.render();
},
render: function() {
var element = this.template(this.model.attributes);
this.$el.append(element);
}
});
(function(){
var item = new itemModel;
var lists = new listView({ model: item });
}());
</script>
</body>
</html>
まとめ
grunt-contrib-jstでJSテンプレートを外部ファイルtemplate.jsとして出力まで試してみました。自分的には以下の利点があるかと思いました。
- 1.ソースコード内にテンプレートを記述しなくて良い。
- grunt-contrib-jstで変換されたjsファイルを読み込むだけで良い。
- 2.テンプレートの管理が楽チン
- 監視フォルダ[assets/templates/]の各htmlがテンプレートとなるため、該当するテンプレートの管理・編集が容易になります。