implementation module HtmlUtil import Html, JSON, Text, Http import StdList embeddedStyle :: HtmlTag embeddedStyle = StyleTag [TypeAttr "text/css"] [RawText css] where css = "body { background: #fff; font-family: Verdana, Arial, sans-serif; font-size: 12px;} th { text-align: left; } " +++ ".field-error em {color: #f00; font-weight: bold} .field-error input {border-color: #f00;} " +++ "#main {margin: 20px; background: #d1dded; border: solid 2px #3a81ad; -moz-border-radius: 5px; background: -moz-linear-gradient(bottom, #d1dded, #fff);} " +++ "#content { padding: 10px; } " +++ ".buttons { padding: 5px; background-color: #3a81ad; } " +++ ".section { margin: 10px; padding: 5px; overflow: auto;} " +++ ".description { margin: 0px 15px 0px 15px; } " +++ ".parameters th, { width: 150px; } " +++ ".json { font-family: Courier, monotype; font-size: 12px;} " +++ ".json ul { padding-left: 15px;} " +++ "h1 { margin: 10px 15px 10px 15px; font-weight: normal; font-size: 24px;} " +++ "h2 { margin: 5px 5px 5px 0px; font-weight: bold; font-size: 14px; border: solid #999; border-width: 0px 0px 1px 0px;} " +++ "p { margin: 0px 0px 10px 0px; } " +++ "button {-moz-border-radius: 3px; }" pageLayout :: !String !String ![HtmlTag] -> HtmlTag pageLayout title description content = HtmlTag [] [head,body] where head = HeadTag [] [TitleTag [] [Text title], embeddedStyle] body = BodyTag [] [DivTag [IdAttr "main"] (header ++ content)] header = [H1Tag [] [Text title],PTag [] [DivTag [ClassAttr "description"] [RawText description]]] servicePage :: !String !String !String ![(String,String,Bool)] JSONNode -> HtmlTag servicePage title description url params json = pageLayout title description [parameters, message, alternatives] where parameters = pageSection "Parameters" [FormTag [ActionAttr url,MethodAttr "get"] [TableTag [ClassAttr "parameters"] (rows ++ send)]] rows = [TrTag [] [ThTag [] [Text n : if o [Text "*:"] [Text ":"]], TdTag [] [InputTag [NameAttr n, ValueAttr v]]] \\ (n,v,o) <- params] send = [TrTag [] [TdTag [ColspanAttr "4"] [ButtonTag [TypeAttr "submit"] [Text "Send"]]]] message = pageSection "Data" [DivTag [ClassAttr "json"] (formatJSON json)] jsonurl = replaceSubString "services/html" "services/json" url alternatives= pageSection "Alternative representations" [PTag [] [Text "JSON: ", ATag [HrefAttr jsonurl] [Text jsonurl]]] serviceResponse :: !Bool !String !String !String ![(String,String,Bool)] JSONNode -> HTTPResponse serviceResponse html title description url params json = if html {http_emptyResponse & rsp_data = toString (servicePage title description url params json)} {http_emptyResponse & rsp_data = toString json} formatJSON :: JSONNode -> [HtmlTag] formatJSON (JSONNull) = [Text "null"] formatJSON (JSONBool True) = [Text "true"] formatJSON (JSONBool False) = [Text "false"] formatJSON (JSONInt i) = [Text (toString i)] formatJSON (JSONReal r) = [Text (toString r)] formatJSON (JSONString s) = [Text "\"", Text s, Text "\""] formatJSON (JSONArray items) = [UlTag [] [LiTag [] (formatJSON node) \\ node <- items] ] formatJSON (JSONObject fields) = [UlTag [] [LiTag [] [Text label,Text ": " :formatJSON node] \\(label,node) <- fields ] ] formatJSON (JSONRaw r) = [PreTag [] [Text (toString r)]] formatJSON _ = [] overviewPage :: HtmlTag overviewPage = pageLayout "Services" description [application,sessions,workflows,tasks,users,documents] where description = "This application can be accessed through a RESTful JSON API.
Below is an overview of the available service urls." application = pageSection "application" [ATag [HrefAttr "html/application"] [Text "General information information about this application"]] sessions = pageSection "sessions" [ATag [HrefAttr "html/sessions"] [Text "Authentication and session management"]] workflows = pageSection "workflows" [ATag [HrefAttr "html/workflows"] [Text "A catalogue of available workflows"]] tasks = pageSection "tasks" [ATag [HrefAttr "html/tasks"] [Text "Listing of and working on tasks"]] users = pageSection "users" [ATag [HrefAttr "html/users"] [Text "User management"]] documents = pageSection "documents" [ATag [HrefAttr "html/documents"] [Text "Upload/download of binary files"]] overviewResponse :: HTTPResponse overviewResponse = {http_emptyResponse & rsp_data = toString overviewPage} redirectResponse :: !String -> HTTPResponse redirectResponse url = {HTTPResponse | rsp_headers = [("Status","302 - Found"),("Location",url)], rsp_data = ""} notFoundPage :: !HTTPRequest -> HtmlTag notFoundPage req = pageLayout "404 - Not Found" "" message where message = [DivTag [IdAttr "content"] [Text "The resource you tried to access ",StrongTag [] [Text req.req_path], Text " could not be found."]] notFoundResponse :: !HTTPRequest -> HTTPResponse notFoundResponse req = {HTTPResponse | rsp_headers = [("Status","404 - Not Found")], rsp_data = toString (notFoundPage req)} pageSection :: !String ![HtmlTag] -> HtmlTag pageSection title content = DivTag [ClassAttr "section"] [H2Tag [] [Text title]:content] paramValue :: !String !HTTPRequest -> String paramValue name req = http_getValue name (req.arg_post ++ req.arg_get) ""