今回書いた全ソースコードはgithubのリポジトリのtut2ディレクトリにあります.
POSTを処理するサービスを記述するには,POST単体だけではダメで,そのサービスのURIがGETリクエストされた時の処理も書かないといけません.
EliomではEliom_services.post_service関数の~fallbackにGETを処理するサービスを指定します.~post_paramsにはGETのときと同様にパラメータを記述します.
let comment_service = Eliom_services.post_service ~fallback:main_service ~post_params:(string "name" ** string "comment" ** string "submit") () |
サービスでどんなページを表示するかはGETのときと似たような感じです(今回は関数が2つに分割されてるけど).ページの内容を返す関数の第二引数の記述に注意.どうやら(param1, (param2, (param3, …)))と書かないといけないようで.
let comment_page = Eliom_output.Html5.register ~service:comment_service (fun () (name, (comment, _)) -> let message = name ^ "さんのコメント: " ^ comment in Lwt.return (html (head (title (pcdata "")) []) (body [p [pcdata message]]))); |
テスト用のHTMLが以下.
<html> <head><title>post</title></head> <body> <form action="http://localhost:8080/index" method="post"> name: <input type="text" name="name"><br> comment: <input type="text" name="comment"><br> <input type="submit" name="submit" value="Submit"> </form> <body> </html> |
これに適当に入力してsubmitすると以下のようになるはず.
なお,この場合,Eliom_services.post_serviceの~post_paramsにはちゃんとstring “submit”を入れておかないと「パラメータが合わねえよ」と怒られます.パラメータの過不足は許容されないっぽい?
追記: Eliom_parameters.optを使って,opt (string “submit”)と書けばオプショナルなパラメータを作れるようなので不足する分にはよさそうです.