Ocsigen/Eliomの入力値検査

Ocsigenで簡単なサンプルを書いた。 簡単すぎて悲しくなるけど、最初はこんなもんだろう。今週でこれをそこそこの規模に成長させる予定です。

  • 足し算アプリ
  • Struts にあるような入力値の検査機能(その業界ではバリデーションといいます)はOcsigenにはないので、自前で実装した (iferror関数)
  • 入力値はページを移動すると消える

手順

以下、前回 の通りにライブラリがインストールされているとして:
test.ml を、

ocamlfind ocamlc -c -thread -package ocsigen -pp "camlp4o /opt/local/lib/ocaml/site-lib/ocsigen/xhtmlsyntax.cma -loc loc" test.ml

コンパイル。 test.cmo を生成。
/etc/ocsigen/ocsigen.conf

    <host charset="utf-8">
      <site path="test" charset="utf-8">
    	<eliom module='/path/to/test.cmo'/>
      </site>
    </host>  

Ocsigen を起動する。

/usr/local/bin/ocsigen

動作

http://localhost:8080/test/toppage にアクセス。

最初

bに文字列が入っているのでエラー。 検査に失敗してもそれまでに入力していた値は消えてしまうというダメ仕様。

両方に整数を入力すると、計算結果が表示される。

ソース

  • test.ml
open Eliom_predefmod.Xhtml (* get_form, int_input, register *)
open Eliom_services (* new_service *)
open Eliom_parameters (* int, unit, ** *)
open XHTML.M (* pcdata *)
open Lwt (* return *)

(* バリデーション exns に param_name に関する例外が含まれると page を それ以外は pcdata "" を返す *)
let iferror param_name exns page = 
  match exns with 
    | None -> pcdata ""
    | Some exns ->
	let str = string_of_param_name param_name in 
	  if List.exists (fun (pn, _) -> pn=str) exns then page else pcdata ""

(* サービスの定義 *)
let adder =
  new_service 
    ~path:["adder"]
    ~get_params:(int "a" ** int "b")
    ()

let toppage = 
  new_service
    ~path:["toppage"]
    ~get_params:unit
    ()

(* フォーム部分 *)
let adderform exns sp = 
  get_form 
    adder 
    sp 
    (fun (an, bn) -> 
       [ << 
	 <div>
	 a: $int_input ~input_type:`Text ~name:an ()$ 
	 $iferror an exns << <span style='color:red'>整数値を入力してください。</span> >> $
	 <br/>
	 b: $int_input ~input_type:`Text ~name:bn ()$ 
	 $iferror bn exns << <span style='color:red'>整数値を入力してください。</span> >> $
	 </div> >> ])

(* ページ本体 *)
let adderpage ?exns ?params sp = <<
  <html>
    <head>
      <meta http-equiv='Content-Type' content='text/html;charset=utf-8'/>
      <title>Adder</title>
    </head>
  <body> 
    $ adderform exns sp (* フォーム部分を埋め込み *) $ 
    <div>
      $ pcdata (match params with (* 足し算の答えを表示 *)
		  None -> "" 
	        | Some (a,b) -> string_of_int (a+b)) $
    </div>
  </body>
  </html> >>

(* サービスの登録 *)
  let _ = 
    register
      ~service:adder
      ~error_handler:(fun sp exns -> return (adderpage ~exns:exns sp))
      (fun sp params _ -> return (adderpage sp ~params:params));
    register
      ~service:toppage
      (fun sp _ _ -> return (adderpage sp))

ocsforge とかを探せば良いライブラリがあるだろうか?。