//tips
//smart contract
ここからは単にhtmlのファイルではなく、プログラム側で操作できるようなnode.jsのテンプレートエンジンを利用していく。
テンプレートエンジンはhtmlにデータを変換する仕組みで、プログラムの中からhtml表示を操作することを可能にする。
Node.jsではEJSがそれに当たる。
このパッケージのインストールは、node.jsのパッケージをあらかじめまとめて管理しているパッケージマネージャーのnpmを通して取得することになる。
npm install ejs
早速index.ejsファイルを作成していく。
テンプレートを表示させるステップとしては、
・テンプレートファイルの読み込み
・レンダリング テンプレートをもとに表示HTMLを生成
・生成内容の表示出力 htmlをjsのresponse.writeで出力
となる。
const http=require('http');
const fs=require('fs');
const ejs=require('ejs');
//テンプレートファイルの読み込み
//fs.readFileSync(ファイル名,エンコーディング) 同期処理でファイルを読み込むためコールバック不要
//ここで同期処理を使用しているのはサーバでの受付を開始する前だから問題ない。ユーザーが入って来れない状況なので。
const index_page=fs.readFileSync('./index.ejs','utf8');
var server=http.createServer(getFromClient);
server.listen(3000);
console.log('server start');
//createServerの処理
function getFromClient(request,response){
//非同期処理:処理が終わる前に次に進む。その代わり完了時点で実行するコールバック関数が必要
var content=ejs.render(index_page);
response.writeHead(200,{'Content-Type':'text/html'});
//レンダリングしたものを出力するという処理をするため一工程多い
response.write(content);
response.end();
}
EJSでは<%= title %>のように特殊なタグを使い指定した変数の値を出力できる。
function getFromClient(request,response){
//非同期処理:処理が終わる前に次に進む。その代わり完了時点で実行するコールバック関数が必要
//ejs.render(レンダリングするデータ,オブジェクト)
//オブジェクトの変数の値が渡される
var content=ejs.render(index_page,{
title:"indexページ",
content:"これはサンプル"
});
response.writeHead(200,{'Content-Type':'text/html'});
//レンダリングしたものを出力するという処理をするため一工程多い
response.write(content);
response.end();
}
Ejsでは下記のように書かれることになる。
<body>
<header>
<h1><%=title %></h1>
</header>
<div role="main">
<p><%= content %></p>
</div>
</body>
</html>
Style.sssでスタイル部分を別のシートに移す。
<link type ="text/css" href="./style.css" rel="stylesheet">
これでindex.ejsから参照できるようにする。
ただ、この時点ではどのアドレスにアクセスしたらどのような内容を出力するかの処理を行えていないのでstyle sheetの内容は反映されない。
どのアドレスにアクセスしたらどのコンテンツを出力するかというルーティングを設定する必要がある。
例えば、末尾が
/のものにはAを返す
/helloのものにはBを返す
/okのものにはCを返す
などを設定する必要がある。
そのためにはクライアントがアクセスしてきたアドレスを事前に知る必要がある。
const url= require(‘url’);
このurlオブジェクトにはurlのデータを解析して本来の状態に組み立て直す機能がある(パース処理)ので、それを利用して、ドメインより下のパス部分の値をチェックし、それに応じて処理を分岐させる。
Requestからうまく取り出せればいいので、基本型は下記のようになる。
//クライアントの要求アドレスの取得
var url_parts=url.parse(request.url);
switch(url_parts.pathname){
//caseの中でpathnameに該当する部分があるかを調べる事ができる
case”/hello”:
break;
…
}
この内容をapp.jsに反映。
const http=require('http');
const fs=require('fs');
const ejs=require('ejs');
const url=require('url');
//テンプレートファイルの読み込み
//fs.readFileSync(ファイル名,エンコーディング) 同期処理でファイルを読み込むためコールバック不要
//ここで同期処理を使用しているのはサーバでの受付を開始する前だから問題ない。ユーザーが入って来れない状況なので。
const index_page=fs.readFileSync('./index.ejs','utf8');
const style_css=fs.readFileSync('./style.css','utf8');
var server=http.createServer(getFromClient);
server.listen(3000);
console.log('server start');
//createServerの処理
function getFromClient(request,response){
var url_parts=url.parse(request.url);
switch(url_parts.pathname){
case '/':
var content =ejs.render(index_page,{
title:"Index",
content:"これはサンプルページです"
})
response.writeHead(200,{'Content-Type':'text/html'});
response.write(content);
response.end();
break;
case '/style.css':
response.writeHead(200,{'Content-Type':'text/css'});
response.write(style_css);
response.end();
break;
default:
response.writeHead(200,{'Content-Type':'text/plain'});
response.end('no page...');
break;
}
}
後で以前作成したクラウドファンディングdappを振り返ると良いかもしれない。かなり実践で使われている内容が出てきている。