2015年8月29日土曜日

Expressであえて静的なファイルを生成してみる

たとえば、以下の2種類のJade定義を用意します。

1) base.jade:

doctype html
html
  head
    title= title
    link(rel='stylesheet', href='/stylesheets/style.css')
  body
    block content

2) extend.jade:

extends base

block content
  h1= title
  p Welcome to #{title}

これは、2)のHTML出力用に定義した extend.jade をテンプレートとして、これから HTML を生成しようと思います。
しかし、上記には構造上のちょっとした工夫があって、extend.jade は、1)の base.jade を継承しています。
具体的には、おおまかなレイアウトは base.jade が担い、body の部分を extend.jade に差し替えています。
それが、block content という記述です。

さらに、Nodeのほうでは、HTML をレンダリングするのではなく静的な HTML ファイルを物理的に生成しようと思います。
それが次のコードです。

まずは、ルーティングの部分にRESTのPostリクエストを、app.js に記述します。
var output = require('./routes/output')
app.use('/output/:param', output);

次に処理の部分を output.js に記述します。
var express = require('express');
var router = express.Router();

var jade = require('jade'),
    fs = require('fs');

/* POST listing. */
router.post('/', function (req, res) {

  // 事前条件は省略 ・・・

    fs.readFile('./views/extend.jade', 'utf8', function (err, source) {
        if (err) throw err;
        console.log(source);
        var opts = {
            pretty: true, filename: './views/base.jade'
        };
        var template = jade.compile(source, opts);
        html = template(body);
        fs.writeFile('./public/test_file.html', html);
    });

  // レスポンス処理は省略 ・・・
});

module.exports = router;


通常、このようなコードを書くことはないと思いますが、実験です。あえて静的なHTMLをレンダリングするのではなく実体を出力します。
ポイントは、jade.compile() の第2引数として与える opts のパラメータに jadeの継承元のファイルを指定してあります。

では、POSTでリクエストします。URLはこんな感じです。当然 JSONプロトコルです。
http://XXX.XXX.XXX.XXX:YYYY/output/param

そして body はこんな感じ。
{
  "title": "test_parameter"
}

生成された HTML ファイルは以下のようになります。
<!DOCTYPE html>
<html>
  <head>
    <title>test_parameter</title>
    <link rel="stylesheet" href="/stylesheets/style.css">
  </head>
  <body>
    <h1>test_parameter</h1>
    <p>Welcome to test_parameter</p>
  </body>
</html>

という検証結果でした。
今回はノンブロッキングIOに関する考察は省略しましたが、この部分は注意してください。

0 件のコメント :

コメントを投稿