1 ! Copyright (C) 2008, 2009 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: accessors assocs combinators fry furnace.conversations
4 furnace.utilities html.forms html.templates.chloe http
5 http.server http.server.responses kernel namespaces sequences
6 splitting urls validators ;
11 TUPLE: action rest init authorize display validate submit update replace ;
13 : new-action ( class -- action )
14 new [ ] >>init [ ] >>validate [ ] >>authorize ; inline
16 : <action> ( -- action )
19 : merge-forms ( form -- )
21 [ [ errors>> ] bi@ append! drop ]
22 [ [ values>> ] bi@ assoc-union! drop ]
23 [ validation-failed>> >>validation-failed drop ]
26 : set-nested-form ( form name -- )
30 unclip [ set-nested-form ] nest-form
33 : restore-validation-errors ( -- )
35 nested-forms cget set-nested-form
38 : handle-get ( action -- response )
43 [ authorize>> call( -- ) ]
44 [ drop restore-validation-errors ]
45 [ display>> call( -- response ) ]
48 ] with-exit-continuation ;
50 CONSTANT: revalidate-url-key "__u"
52 : revalidate-url ( -- url/f )
53 revalidate-url-key param
54 dup [ >url ensure-port [ same-host? ] keep and ] when ;
56 : validation-failed ( -- * )
57 post-request? revalidate-url and [
59 nested-forms-key param " " split harvest nested-forms cset
61 <continue-conversation>
65 : handle-post ( action -- response )
68 [ validate>> call( -- ) ]
69 [ authorize>> call( -- ) ]
70 [ submit>> call( -- response ) ]
73 ] with-exit-continuation ;
75 : handle-put ( action -- response )
78 [ validate>> call( -- ) ]
79 [ authorize>> call( -- ) ]
80 [ replace>> call( -- response ) ]
83 ] with-exit-continuation ;
85 : handle-patch ( action -- response )
88 [ validate>> call( -- ) ]
89 [ authorize>> call( -- ) ]
90 [ update>> call( -- response ) ]
93 ] with-exit-continuation ;
95 : handle-rest ( path action -- )
96 rest>> [ [ "/" join ] dip set-param ] [ drop ] if* ;
98 : init-action ( path action -- )
102 M: action call-responder* ( path action -- response )
104 request get method>> {
105 { "GET" [ handle-get ] }
106 { "HEAD" [ handle-get ] }
107 { "POST" [ handle-post ] }
108 { "PUT" [ handle-put ] }
109 { "PATCH" [ handle-patch ] }
113 M: action modify-form
114 drop url get revalidate-url-key hidden-form-field ;
116 : check-validation ( -- )
117 validation-failed? [ validation-failed ] when ;
119 : validate-params ( validators -- )
120 params get swap validate-values check-validation ;
122 : validate-integer-id ( -- )
123 { { "id" [ v-number ] } } validate-params ;
125 TUPLE: page-action < action template ;
127 : <chloe-content> ( path -- response )
128 resolve-template-path <chloe> <html-content> ;
130 : <page-action> ( -- page )
131 page-action new-action
132 dup '[ _ template>> <chloe-content> ] >>display ;