C++にはテンプレートシステムが標準でサポートされていないため、CGIといったWebアプリが作りにくい。たとえばC++でCGIを書くと、
std::cout<< "<table><tr><td>Value</td><td>" << dValue<< "</td></tr></table>"<< std::endl;
といったようにHTMLがコードの中に入ってしまい、Webデザインの変更をするにはC++のソースを変更しコンパイルしなければならない。 つまりC++でCGIを書くとプレゼンテーション(見ため)とロジック(処理)の分離が難しいのである。 一方JavaはJSPというテンプレートシステムをSunが実装したため、比較的楽にWebアプリを作る事ができる。 GoogleがC++のテンプレートシステムを実装し、公開した。それがGoogle Ctemplateだ。まだバージョンは0.1だが、結構使えそうである。早速試してみた。
現在はLinux版だけのようである。Windows版はない。コンパイルできるかもしれないが、試していない。 インストールは簡単。ソースを落して、展開して、./configure; make; make install。 試しに使うだけなら--prefix=$HOME/usrとでもすればOKだろう。 RPMな人はrpmパッケージを落したほうが、もちろん簡単だ。 packageディレクトリにdeb.shとdebというスクリプトとディレクトリがある。debパッケージが作れそうである。試してみたがcontrol fileのsyntax errorでコケたので保留。
以下のテンプレートファイルと、C++ソースで試してみた。
// test.cc
#include<string>
#include<iostream>
#include<google/template.h>
int main(void){
google::TemplateDictionary dict("example");
dict.SetValue("TITLE", "Hello Google C Template");
dict.SetValue("HEADER", "&");
std::string out;
google::Template *tpl = google::Template::GetTemplate("test.tpl", google::DO_NOT_STRIP);
tpl->Expand(&out, &dict);
std::cout<< out<< std::endl;
return 0;
}
<!-- test.tpl -->
<html>
<head><title>{{TITLE}}</title></head>
<body
<h1>{{HEADER:h}}</h1>
</body>
</html>
コンパイルする。
% g++ test.cc -lpthread -lctemplate
実行結果は
$ ./a.out
<!-- test.tpl -->
<html>
<head><title>Hello Google C Template</title></head>
<body
<h1>&</h1>
</body>
</html>
となった。目論見通り、テンプレートの{{TITLE}}がHello Google C Templateという文字列に置き換わっている。また{{HEADER:h}}が&にエスケープされている。これは{{HEADER}}ではなく{{HEADER:h}}としたためである。:hを付けるとhtmlエスケープをやってくれる。:jを付けるとjavascriptエスケープをやる。 ソースを見るとエスケープを処理している部分は、Fanctorとテンプレートで実装されていた。Modern C++ Designにあったポリシークラスだ。
今回は「試し」ということで、{{TITLE}}や{{HEADER}}といったKeyをハードコートしたが、make_tpl_varnames_hを実行しテンプレートファイルをチェックし、make_tpl_varnames_hが吐くヘッダファイルを使うべきだろう。 今回はCGIに使えるということでGoogle Ctemplateを紹介したが、これは汎用のテンプレートシステムなので、CGI以外にも使うことができる。