連載
» 2009年02月19日 00時00分 UPDATE

Gaucheでメタプログラミング(4):Gaucheでテンプレートエンジンを作る (1/2)

Lispの一種であるScheme。いくつかある処理系の中でも気軽にスクリプトを書けるGaucheでLispの世界を体験してみよう(編集部)

[吉田裕美,有限会社イーワイオフィス]

 前回「GaucheでRDBプログラミング」に続き、Webプログラミングです。WebアプリケーションやGUIアプリケーションのように、人との対話があるアプリケーションは一般にMVCを採用しています。

 MVCとは、計算やデータ処理部分のモデル、表示部分のビュー、全体の流れを制御する部分のコントローラにモジュールを分割して作る技法です。

 MVCを採用すると、変更に強いメンテナンス性の高いソフトウェアになるといわれています。実際に、多数のWebアプリケーションフレームワークがMVCを採用しています。

 前回のRDBプログラミングはモデル部分の中心になるものでしたが、今回はビューの部分を作っていきましょう。

HTMLの生成

 Webアプリケーションでは、Webブラウザからのリクエストに対し、サーバ側でHTMLを組み立ててWebブラウザに戻します。HTMLは、開始タグ、内容、終了タグという要素の集まりで、さらに内容の部分に要素を書くことができる再帰的な構造をしています。

 例えば、この連載の第2回「Gaucheでプログラミング」で書いた、何曜日かを表示するCGIが作るHTMLは以下のようになっています。

<html>
  <head><title>曜日</title></head>
  <body>
    2009 年 1 月 31 日は土曜日です
  </body>
</html>

 このような再帰的な構造は、下のようにS式で表すことができます。S式では、1つの要素をリストで表すので終了タグは不要になります。

(html
  (head (title "曜日"))
  (body "2009 年 1 月 31 日は土曜日です")
)

 Gaucheには、text.html-liteというモジュールがあり、上に書いたようなS式で簡単にHTMLを扱えます。連載の第2回で書いた何曜日かを表示するCGIをtext.html-liteを使って書くと以下のようになります。

#!/usr/local/bin/gosh
 
(use www.cgi)
(use srfi-19)
(use text.tree)
(use text.html-lite)
 
(define JST-TZ (* 9 60 60))
(define day-names-array '#("日" "月" "火" "水" "木" "金" "土"))
 
(define (day-name y m d)
  (ref day-names-array (date-week-day (make-date 0 0 0 0 d m y JST-TZ))))
 
(define (main args)
  (let* ((params (cgi-parse-parameters))
         (y (cgi-get-parameter "y" params :convert string->number))
         (m (cgi-get-parameter "m" params :convert string->number))
         (d (cgi-get-parameter "d" params :convert string->number)))
    (print "Content-Type: text/html; charset=utf-8\n")
    (print (tree->string
            (html:html
             (html:head (html:title "曜日"))
             (html:body
              #`",y 年 ,m 月 ,d 日は ,(day-name y m d)曜日です"))))))

テンプレートエンジンを作ってみる

 S式によるHTML表記は、Lispプログラマには支持されますが、デザイナーが作ったHTMLを基にView部分を作るためには、HTMLからS式に変換する手間が掛かります。

 そこでJavaのJSPやRubyのERBのような、HTMLに少し手を入れるだけでView部分が作れるようなテンプレートエンジンを作ってみることにします。

テンプレートエンジンの仕組み

 以下のテンプレートは0、30、45、60、90度のsinの値をTABLEで表示するものです。

<html><body>
<table>
<% (use math.const)
   (use gauche.collection) %>
<% (for-each (lambda(d) %>
  <tr>
    <td> <%= d %> </td><td> <%= (sin (* d pi/180)) %> </td>
  </tr>
<% ) '#(0 30 45 60 90)) %>
</table>
</body></html>

 JSPと同様に、<% 〜 %>の〜にはGaucheのコードが書かれ、実行されます。また、<%= 〜 %>は〜を実行した値に置き換えられます。

 JSPは、Javaに変換され、コンパイルされ実行されますが(詳しくは、@ITのJSPの記事を調べてみてください)、ここでも同じようにテンプレートをGaucheのプログラムに変換し実行することにします。変換されたGaucheのプログラムは、以下のようになります。

(begin
 (display "\n<html><body>\n<table>\n")
 (use math.const)
 (use gauche.collection)
 (for-each
  (lambda (d)
    (display "\n  <tr>\n    <td> ")
    (display d)
    (display " </td><td> ")
    (display (sin (* d pi/180)))
    (display " </td>\n  </tr>\n"))
  '#(0 30 45 60 90))
 (display "\n</table>\n</body></html>\n"))

 テンプレートの変換のルールは、

  • HTMLの部分は文字列として、display関数で出力されます
  • <% 〜 %>の内部はそのままプログラムになります
  • <%= 〜 %>は〜の値を出力するので(display 〜)になります

というものです。

       1|2 次のページへ

Copyright© 2017 ITmedia, Inc. All Rights Reserved.

@IT Special

- PR -

TechTargetジャパン

この記事に関連するホワイトペーパー

Focus

- PR -

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。