SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

特集記事

ApacheModuleでWebアプリケーションをつくろう

コーディングでApacheModuleの開発プロセスをまなぶ

  • このエントリーをはてなブックマークに追加

6.テンプレートエンジンClearSilverを適用

 さて今度は自動生成したApache Moduleに、「ClearSilver」を適用します。C言語のみで画面出力を行おうとすると処理が煩雑になってしまうためです。ClearSilverはバグトラッキングツール「Trac」でも使用されているC言語で作成されたテンプレートエンジンです。JavaのWebアプリケーションで言うところのJSPなど画面表示を担当する箇所とイメージしてもらうとわかりやすいかもしれません。

 この章で行う作業は以下のとおりです。

  • Apache Moduleの修正
  • Makefileの修正
  • テンプレートファイルの作成
  • Apache Moduleの動作確認

Apache Moduleの修正

 まずは、Apache Moduleの修正から行いましょう。

対応するサンプルコード
ClearSilver適用後のmod_test.c
 40 #define ap_psprintf apr_psprintf
 41
 42 #include "httpd.h"
 43 #include "http_config.h"
 44 #include "http_protocol.h"
 45 #include "ap_config.h"
 46 #include "ClearSilver.h"
 47
 48
 49 static NEOERR *render_cb(void *obj, char *s)
 50 {
 51     request_rec *r = (request_rec *)obj;
 52     ap_rputs(s, r);
 53     return STATUS_OK;
 54 }
 55
 56 static void output_handler(request_rec *r)
 57 {
 58     HDF *hdf;
 59     CSPARSE *cs;
 60
 61     const char *arrayname[4] =
             { "FOO", "BAR", "HOGE", "MONA" };
 62     int i;
 63     hdf_init(&hdf);
 64
 65     for( i = 0; i < 4; i++ )
 66     {
 67         hdf_set_value(hdf, ap_psprintf(r->pool, 
                 "csdata.%d.arrayname", i ), arrayname[i] );
 68     }
 69
 70     cs_init(&cs, hdf);
 71     cs_parse_file(cs, "/usr/local/src/modtest/test/test.cs");
 72     cs_render(cs, r, render_cb);
 73     cs_destroy(&cs);
 74     hdf_destroy(&hdf);
 75 }
 76
 77
 78
 79 /* The sample content handler */
 80 static int test_handler(request_rec *r)
 81 {
 82
 83     if (strcmp(r->handler, "test")) {
 84         return DECLINED;
 85     }
 86
 87     r->content_type = "text/html";
 88
 89     if (!r->header_only)
 90         output_handler(r);
 91     return OK;
 92 }
 93
 94 static void test_register_hooks(apr_pool_t *p)
 95 {
 96     ap_hook_handler(test_handler, NULL, NULL, APR_HOOK_MIDDLE);
 97 }
 98
 99 /* Dispatch list for API hooks */
100 module test_module = {
101     STANDARD20_MODULE_STUFF,
102     NULL,                /* create per-dir    config structures */
103     NULL,                /* merge  per-dir    config structures */
104     NULL,                /* create per-server config structures */
105     NULL,                /* merge  per-server config structures */
106     NULL,                /* table of config file commands       */
107     test_register_hooks  /* register hooks                      */
108 };
109

 ClearSilverの関数を使用するため、46行目でヘッダファイル「ClearSilver.h」をインクルードしています。以下に使用する関数を記載します。これらの関数についてはmanコマンドでAPIを調べることができます。

#include <cs/cs.h>
NEOERR *cs_init (CSPARSE **parse, HDF *hdf);
#include <cs/cs.h>
NEOERR *cs_parse_file (CSPARSE *parse, const char *path);
#include <cs/cs.h>
NEOERR *cs_render (CSPARSE *parse, void *ctx, CSOUTFUNC cb); 
#include <cs/cs.h>
void cs_destroy (CSPARSE **parse);

 参考までに上記3つの各関数の戻り値である構造体NEOERRは以下のようになっています。

構造体 NEOERR
util/neo_err.h(50行目から61行目)
typedef struct _neo_err 
{
  int error;
  int err_stack;
  int flags;
  char desc[256];
  const char *file;
  const char *func;
  int lineno;
  /* internal use only */
  struct _neo_err *next;
} NEOERR;

 テンプレートファイルとのデータ授受には多次元データを表す汎用形式hdh(Hierarchical Data Format)を使用するため、これに関連する関数も使用することになります。この関数もmanコマンドを利用することによってAPIを調べることができます。

#include <util/neo_hdf.h>
NEOERR* hdf_init (HDF **hdf);
#include <util/neo_hdf.h>
NEOERR* hdf_set_value
    (HDF *hdf, const char *name, const char *value);
#include <util/neo_hdf.h>
void hdf_destroy (HDF **hdf);

 なお、40行目は単純に「ap_psprintf」を「apr_psprintf」と定義しています。ヘッダファイルを作成する量ではないので、直接ソースファイルに記載しても問題ないとの判断したためです。また、apr_psprintfのAPIは以下のとおりです。

apr_strings.h 内
APR_DECLARE_NONSTD(char *)
    apr_psprintf(apr_pool_t *p, const char *fmt, ...)
__attribute__((format(printf,2,3)));

Makefileの修正

 ClearSilverの利用に伴いMakefileも変更する必要があります。

対応するサンプルコード
Makefile
  1 ##
  2 ##  Makefile -- Build procedure for sample test Apache module
  3 ##  Autogenerated via ``apxs -n test -g''.
  4 ##
  5
  6 builddir=.
  7 top_srcdir=/usr/local/apache22
  8 top_builddir=/usr/local/apache22
  9 include /usr/local/apache22/build/special.mk
 10
 11 #   the used tools
 12 APXS=apxs
 13 APACHECTL=apachectl
 14
 15 #   additional defines, includes and libraries
 16 #DEFS=-Dmy_define=my_value
 17 #INCLUDES=-Imy/include/dir
 18 #LIBS=-Lmy/lib/dir -lmylib
 19 INCLUDES=-I/usr/local/include/ClearSilver
 20 LIBS=-lneo_cs -lneo_utl
 21
 22 #   the default target
 23 all:
 24         $(APXS) -c $(INCLUDES) $(LIBS) -Wl,-g mod_test.c
 25
 26 #   install the shared object file into Apache
 27 install: install-modules-yes
 28
 29 #   cleanup
 30 clean:
 31         -rm -f mod_test.o mod_test.lo mod_test.slo mod_test.la
 32
 33 #   simple test
 34 test: reload
 35         lynx -mime_header http://localhost/test
 36
 37 #   install and activate shared object by reloading Apache to
 38 #   force a reload of the shared object file
 39 reload: install restart
 40
 41 #   the general Apache start/restart/stop
 42 #   procedures
 43 start:
 44         $(APACHECTL) start
 45 restart:
 46         $(APACHECTL) restart
 47 stop:
 48         $(APACHECTL) stop
 49

 まずは、19行目の変数INCLUDESに、ClearSilverのインクルードファイルの保管されているディレクトリを設定します。次に20行目の変数LIBSに必要なライブラリファイルを登録します(下表参照)。最後に、24行目のallオプション指定時の記述に、変数INCLUDESLIBSを含めたapxsによるコンパイルコマンドを登録すればMakefileの修正は完了です

変数「LIBS」に登録すべきライブラリ
ライブラリファイルLIBへの登録要否
/usr/local/lib/libneo_cgi.a不要
/usr/local/lib/libneo_cs.a
/usr/local/lib/libneo_utl.a

テンプレートファイルの作成

 最後にClearSilverのテンプレートファイル「test.cs」を作成しましょう。

対応するサンプルコード
test.cs
<?cs each:item = csdata ?>
    Hello <?cs var:item.arrayname ?>!<br>
<?cs /each ?>

 上記のコードではcsdataに登録されている要素数分ループを行い、プログラムで作成したhdfデータからarrayname要素の内容を表示する処理を行います。

Apache Moduleの動作確認

 以上の準備が整ったところで動作の確認を行いましょう。まず、Apache HTTP Serverを停止した後、コンパイルとインストールを実行します。

コンパイル・インストールの実行
apachectl stop
make clean
make all install

 Make実行時にエラーが表示されなければ、モジュールの作成と「/usr/local/apache22modules」へのインストールが行われているはずです。

 ここでApacheの起動を行います。「http://(ApahceHTTPサーバが動作しているホスト)/test/」にアクセスして、動作の確認を行いましょう。

Apacheの起動
apachectl start
動作確認結果
動作確認結果

次のページ
7.mod_dbdのデータベースコネクションプールを使用したApacheモジュール

この記事は参考になりましたか?

  • このエントリーをはてなブックマークに追加
特集記事連載記事一覧

もっと読む

この記事の著者

タケル(タケル)

攻殻機動隊の『笑い男』に憧れていて、いつかタチコマには追いつきたいと願うSE

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/2502 2008/06/16 14:30

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング