Text.Htmlを使ってHTMLを出力
やはりCGIはHTMLを出力してこそ。でも文字列連結でHTMLを作るのはちょっとかんべん。
テンプレートエンジンをインストールしてもいいのだけど、GHCに付属しているText.Htmlというライブラリがあったので使ってみました。
Text.Htmlパッケージを触る
押さえておくべき演算子はこれ。
+++
あるノードの後ろに兄弟ノードを追加します。
タグに属性を付与する演算子も大事そう。
!
例えば2つのliタグを入れ子に持つulタグは以下のように表現出来ます。
q = (ulist ! [identifier "a"]) ( li ( primHtml "list1" ) +++ li ( primHtml "list2" ) )
上記コードは以下のHTMLになります。
<UL ID = "a"> <LI> list1 </LI> <LI> list2 </LI> </UL>
使ってみた感想
各タグに相当する便利関数が提供されているものの、タグが大文字で出力されてしまうのがちょっと気持ち悪い。属性名も大文字です。
あと「関数の組み合わせで文書構造を表現する」というアプローチは面白いのですが、HTMLを直接書くのに比べたら、やはり表記が複雑になります。Haskellは表記が簡潔だからそこそこ書けるレベルではありますが、素でHTMLを書くのとは比べるべくもないです。当然ですけど。
CGIに組込む
組み込んでみました。一応、クエリストリングから文字列を得て動的に編集するロジックを入れています。
#! /usr/local/bin/runghc module Main where import Text.Html import Network.CGI import Data.Maybe main = runCGI $ handleErrors $ cgiMain cgiMain :: CGIT IO CGIResult cgiMain = setHeader "Content-Type" "text/html; charset=UTF-8" >> html >>= \html -> output ("<!doctype html>\n" ++ prettyHtml html) html :: MonadCGI m => m Html html = findVar "test" >>= \test -> findVar "var" >>= \var -> return $ header ( meta ! [strAttr "charset" "UTF-8"] +++ thetitle ( primHtml "Welcome, Haskell's CGI world!!" ) ) +++ body ( h1 ( primHtml "aaaaaaaaaaa" ) +++ paragraph ( primHtml "bbbbbbbbbbb" ) +++ h2 ( primHtml var ) +++ paragraph ( primHtml "cccccccccc" +++ ulist ( li ( primHtml "ddddddd" ) +++ li ( primHtml test ) ) ) ) findVar :: MonadCGI m => String -> m String findVar name = getInput name >>= \v -> case v of Just v -> return v Nothing -> return ("**"++name++"**")
ベタだけど、できた!
ただ、モナド地獄に陥ってる感がありますね。全ての関数がモナドに
絡んでて、このままではテストしにくいんじやないかなーと思います。