9 let document heading extra x
=
10 html ~a
:[a_xmlns `W3_org_1999_xhtml
; a_xml_lang
"en"]
11 (head
(title
(t heading
)) extra
)
14 let doc heading x
= document heading
[] x
16 let input_text ~title
() =
17 form ~a
:[a_method `Post
] ~action
:(uri_of_string
"")
20 (p
[textarea ~rows
:20 ~cols
:80 ~a
:[a_name
"text"] (t"")]);
21 (p
[input ~a
:[a_name
"submit"; a_value
"Submit"; a_input_type `Submit
] ()]);
24 let ahref s
= a ~a
:[a_href
(uri_of_string s
)]
30 let arg x
= catch
(fun args
-> let a = List.find
(fun a -> a#name
= x
) args
in a#
value)
32 type location
= string
34 (* **************************** *)
37 module Store
= Storage.Fs
39 let rec resolve self url
=
40 if url
= self#url
then self
41 else List.find
(fun child
-> try ignore
(resolve child url
); true with Not_found
-> false) self#children
45 method virtual url
: location
46 method virtual name
: string
47 method virtual children
: base list
48 method virtual render
: <name
:string;value:string> list
-> html
51 let header self pages
=
52 let name x
= if Oo.id x
= Oo.id self
then [b
[t x#
name]] else [t x#
name] in
53 div
[p
(List.map
(fun p
-> [ahref p#url
(name p
); space
()]) pages
>> List.flatten
); hr
()]
55 let render_markdown s
=
56 let module SM
= Simple_markup
in
57 let render_pre ~kind s
= t s
58 and render_link href
= ahref href
.SM.href_target
[t href
.SM.href_desc
]
59 and render_img i
= img ~src
:(uri_of_string i
.SM.img_src
) ~alt
:i
.SM.img_alt
() in
60 s
>> SM.parse_text
>> Simple_markup__html.to_html ~
render_pre ~render_link ~render_img
63 match Store.get store
(`S
"index") with
65 | Some s
-> Marshal.from_string s
0
67 let log_exn e fmt
= Printf.ksprintf print_endline fmt
69 class view_comment anc
= object(self
)
73 method name = z#view_comment
75 let store = Store.create
"comments" in
78 (fun x
-> li
[ahref (Printf.sprintf
"%s?id=%u" self#url x
) [t (string_of_int x
)]])
79 (List.sort ~cmp
:compare
(get_index store)))
81 let content = match arg "id" args
with
85 match Store.get
store (`I
(int_of_string v
)) with
86 | Some s
-> render_markdown s
>> div
87 | None
-> div
[h1
[t (z#no_item v
)]; show_index ()]
88 with e
-> log_exn e
"view_comments(%s)" v
; show_index ()
90 | None
-> show_index ()
100 exception Redirect
of string
102 class comment ctx
= object(self
)
105 method url
= "/comment"
106 method name = z#add_comment
109 match arg "text" args
with
111 let store = Store.create
"comments" in
112 let index = get_index store in
113 let id = match List.sort ~cmp
:(flip compare
) index with
117 (* FIXME atomicity *)
118 Store.add
store (`S
"index") (Marshal.to_string
(id::index) []);
119 Store.add
store (`I
id) text;
120 raise
(Redirect
(Printf.sprintf
"/view?id=%u" id))
121 | None
-> div
[p
[t ""]]
127 input_text self#
name ()
131 class main
= object(self
)
133 method comment
= new comment self
134 method children
= ([new comment self
; new view_comment self
]:>base list
)
136 method name = z#main_page
141 ul (List.map
(fun x
-> li
[ahref x#url
[t x#
name]]) self#children
);
147 class not_found url
=
152 method name = z#not_found
157 p
[t "Url "; b
[t url
]; t " not found."];