前回は、ラズパイのコントローラ用の画面をBootstrapを使ってざっくりとつくりました。
tohutokonsome.hatenablog.com
今回はその画面をnode.js + expressにのせるにあたってjadeというものが出てきたので、そちらを最初に触れたいと思います。
expressを使用するにあたって、テンプレートエンジンという単語がでてきます。
テンプレートエンジンという単語そのものの意味は置いておいて、私の理解としては動的コンテツを提供する際に、pythonのDjangoだったり、PHPだったりHTML内にスクリプトを埋め込んで、サーバー側が解釈したHTMLをクライアントに返す、そのサーバー側が解釈する際のミドルウェア?を指していると思ってます。
Djangoで言うと以下のようなやつ。
<h3> {{ post.title }}</h3>
expressでもテンプレートエンジンをいくつか選べるのですが、その中でもjadeというものを今回使ってみたいと思います。
ただ、jadeはhtml内に埋め込むお作法どうのこうの以上に、その記法そのものもhtmlとは異なっています。
とはいえ、その目的は生産性をあげるためのものなので、覚えてしまえばきっと楽になるはずです。
なにはともあれ、expressのスケルトンを作成します。
前回もやったので大丈夫です。
$ mkdir legocar_express
$ cd legocar_express
$ express
$.
├── app.js
├── bin
├── node_modules
├── package.json
├── public
├── routes
└── views
expressに必要なパッケージインストールします。
$ npm install
とりあえずさわってみる
素敵なチュートリアルがあるので、これに沿ってやった。
Jade について。 · GitHub
とりあえず、練習用にviews配下に以下のファイルを新規で作成した。
practicejade.jade
doctype html
html
head
meta(charset='UTF-8')
title 最高にクールなホームページ
link(rel='stylesheet', href='./css/app.css')
body
h1 最高にクールなホームページ
p 最高にクールなホームページへようこそ。
script(src='./js/app.js', charset='UTF-8')
表示するために、既存のindex.jsを修正する。
index.js
var express = require('express');
var router = express.Router();
router.get('/', function(req, res, next) {
res.render('index', { title: 'Express' });
});
router.get('/practicejade', function(req, res, next) {
res.render('practicejade');
});
module.exports = router;
これで、「http://localhost:3000/practicejade」にアクセスすると、以下のページが表示される。
これをもとにチュートリアルを行う。
ちなみに、スケルトン作成時に特に指定したわけではないけれども、テンプレートエンジンはjadeになっていたので、こちらに関しては特に変更はしていない。
app.js(抜粋)
app.set('view engine', 'jade');
expressから渡したオブジェクトの値を参照する
jadeの基本的な構文については、チュートリアルに詳しく書かれているので、ここでは詰まったりした部分について記載していく。
まずは、表題の通り、html側で動的に値を表示したい場合とかの一例について。
index.jsファイルの中で定義したオブジェクト「pakage」をrender関数の引数として渡している。
index.js
var package = {
title: '最高にクールなホームページ',
description: '最高にクールなホームページです。見ないと損です。',
keywords: [
'最高',
'クール',
'世界一',
'天才'
],
robots: [
'INDEX',
'FOLLOW',
'NOODP',
'NOYDIR',
'NOARCHIVE'
]
};
router.get('/practicejade', function(req, res, next) {
res.render('practicejade',{package:package});
});
jade側では、渡されたpackageオブジェクトの値は下記のように参照することができるみたい。
いろいろな書き方があって混乱した。
practicejade.jade
doctype html
html
head
meta(charset='UTF-8')
title 最高にクールなホームページ
link(rel='stylesheet', href='./css/app.css')
body
h1 最高にクールなホームページ
p 最高にクールなホームページへようこそ。
h1 Expressから渡されたオブジェクトを参照する
//いろいろな書き方がある。どれがいいんだろう。
p #{package.title}
p= package.description
p!= package.keywords
script(src='./js/app.js', charset='UTF-8')
ブラウザの表示

コレクション要素を表示する
表題があっているか少し怪しい。
さきほどの例のように、要素をひとつずつ表示するのではなく、リスト形式のように並べたいときにforeach構文が使える。
もちろん、for loopみたいなものをあるんだけれども、each構文で詰まったのであえてこちらを記載しておく。
ただ、あんまりしっくり来てないので、Quitaの方で詳しい方からのツッコミ待ちの状態です。
qiita.com
とりあえずコードの中身と表示結果を記載しておく。
practicejade.jade
doctype html
html
head
meta(charset='UTF-8')
title 最高にクールなホームページ
link(rel='stylesheet', href='./css/app.css')
body
h1 最高にクールなホームページ
p 最高にクールなホームページへようこそ。
hr
h1 each構文を使う
ul
//inに直接オブジェクトを記載すると、コンパイルエラーになる。
一旦、変数として定義してあげると問題ない。
each val,key in #{package}
li= key + ':' + val
-var hoge = package
each val,key in hoge
li= key + ':' + val
ブラウザの表示

include
htmlファイルを部品化しておいて、使う側でinlucdeすることで再利用ができる、みたいなやつ。
新たに、includeディレクトリを作成して、その配下に「include_test.jade」を作成した。
├── include
│ ├── include_test.jade
├── practicejade.jade
部品化したファイル側にも#{変数名}の構文は使えるかな、という確認も込めて、package.titleを入れている。
include_test.jade
h3 これは、読み込んだincludeされたファイルです。 #{package.title}
「practicejade_.jade」で上記のファイルをincludeします。
practicejade.jade
doctype html
html
head
meta(charset='UTF-8')
title 最高にクールなホームページ
link(rel='stylesheet', href='./css/app.css')
body
h1 最高にクールなホームページ
p 最高にクールなホームページへようこそ。
script(src='./js/app.js', charset='UTF-8')
//includeのテスト
h1 includeを使う
include ./include/include_test.jadek
ブラウザの表示

extends
オブジェクト指向のインタフェースっぽいという印象を受けた。
extendで大まかなテンプレートを定義しておいて、includeする側で具体的な処理だったりを書くみたいな。
まず、extendされる「exten_test.jade」を作成する。
├── include
│ ├── include_test.jade
│ ├── extend_test.jade
├── practicejade.jade
ファイルの内容は、以下の通り。
extend_test.jade
doctype html
html(lang='ja')
head
meta(charset='UTF-8')
title #{package.title}
body
block content
p 上書きされるのでこれは表示されない。
これを、practicejade.jadeでextendsをして継承している。
practicejade.jade
//extend_test.jadeを継承する
extends ./include/extend_test
//extend_test.jadeのcontent部分を上書きする。
block content
h1 Expressから渡されたオブジェクトを参照する
//いろいろな書き方がある。どれがいいんだろう。
p #{package.title}
p= package.description
p!= package.keywords
hr
h1 each構文を使う
ul
//inに直接オブジェクトを記載すると、コンパイルエラーになる。
一旦、変数として定義してあげると問題ない。
each val,key in #{package}
li= key + ':' + val
-var hoge = package
each val,key in hoge
li= key + ':' + val
hr
//includeのテスト
h1 includeを使う
include ./include/include_test.jade
Bootstrapを準備する
jadeの記法を使って、BootstrapのStarter Templateを作ります。
Bootstrap4.xのStarter Template
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" integrity="sha384-rwoIResjU2yc3z8GV/NPeZWAv56rSmLldC3R/AZzGRnGxQQKnKkoFVhFQhNUwEyJ" crossorigin="anonymous">
</head>
<body>
<h1>Hello, world!</h1>
<script src="https://code.jquery.com/jquery-3.1.1.slim.min.js" integrity="sha384-A7FZj7v+d/sdmMqp/nOQwliLvUsJfDHW+k9Omg/a/EheAdgtzNs3hpfag6Ed950n" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js" integrity="sha384-DztdAPBWPRXSA/3eYEEUWrWCy7G5KFbe8fFjk5JAIxUYHKkDx6Qin1DkWx51bBrb" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js" integrity="sha384-vBWWzlZJ8ea9aCX4pEW3rVHjgjt7zpkNpZk+02D9phzyeVkE+jo0ieGizqPLForn" crossorigin="anonymous"></script>
</body>
</html>
ファイル作成
viewsディレクトリ配下に、以下のファイルを用意しました。
├── include
│ ├── footer.jade
│ ├── header.jade
│ └── scripts.jade
├── index.jade
├── layout.jade
まずはextendsされるlayout.jadeです。
layout.jade
doctype html
html(lang='ja')
head
meta(charset='utf-8')
meta(name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no")
link(rel='stylesheet', href='/stylesheets/style.css')
//Bootstrap ラズパイに乗せる時はCDNは使わないようにしたい
link(rel='stylesheet',href='https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css' integrity="sha384-rwoIResjU2yc3z8GV/NPeZWAv56rSmLldC3R/AZzGRnGxQQKnKkoFVhFQhNUwEyJ" crossorigin="anonymous")
block title
body
include ./include/header
block content
include ./include/footer
include ./include/scripts
- head内のtitleおよびbody内のcontentはextendsする側で再定義します。
- body内の「header」「footer」およびBootstrapに必要なjQueryを書くjavascriptは全ページ共通ということで、layout.jade内でincludeしています。
また、index.jadeの内容は以下の通りとなります。
index.jade
extends ./layout
block title
title レゴカー
block content
h1 Hello World!
ブラウザでみた場合

以上で、node.js + express + jadeでBootstrapを使用したページを作成する準備が整いました。
次回は、前回のリモコンの画面をjadeで書いていきたいと思います。