factor/basis/furnace/actions/actions.factor

121 lines
3.2 KiB
Factor
Raw Normal View History

! Copyright (C) 2008, 2009 Slava Pestov.
2008-03-03 03:19:36 -05:00
! See http://factorcode.org/license.txt for BSD license.
2008-06-02 16:00:03 -04:00
USING: accessors sequences kernel assocs combinators
2008-05-26 01:47:27 -04:00
validators http hashtables namespaces fry continuations locals
2009-03-16 21:11:36 -04:00
io arrays math boxes splitting urls
2008-06-02 16:00:03 -04:00
xml.entities
http.server
http.server.responses
2008-11-24 21:26:11 -05:00
furnace.utilities
2008-07-10 00:41:45 -04:00
furnace.redirection
furnace.conversations
2009-04-06 23:05:17 -04:00
furnace.chloe-tags
html.forms
2008-06-02 16:00:03 -04:00
html.components
html.templates.chloe
2008-09-19 17:36:31 -04:00
html.templates.chloe.syntax
html.templates.chloe.compiler ;
IN: furnace.actions
2008-03-03 03:19:36 -05:00
SYMBOL: rest
2008-05-27 01:01:57 -04:00
TUPLE: action rest init authorize display validate submit ;
2008-03-03 03:19:36 -05:00
2008-05-26 01:47:27 -04:00
: new-action ( class -- action )
new [ ] >>init [ ] >>validate [ ] >>authorize ; inline
2008-03-03 03:19:36 -05:00
2008-05-26 01:47:27 -04:00
: <action> ( -- action )
action new-action ;
2008-07-10 00:41:45 -04:00
: merge-forms ( form -- )
[ form get ] dip
[ [ errors>> ] bi@ append! drop ]
[ [ values>> ] bi@ assoc-union! drop ]
[ validation-failed>> >>validation-failed drop ]
2008-07-10 00:41:45 -04:00
2tri ;
: set-nested-form ( form name -- )
2008-09-06 20:13:59 -04:00
[
merge-forms
] [
2008-07-10 00:41:45 -04:00
unclip [ set-nested-form ] nest-form
2008-09-06 20:13:59 -04:00
] if-empty ;
: restore-validation-errors ( -- )
2008-07-10 00:41:45 -04:00
form cget [
nested-forms cget set-nested-form
] when* ;
2008-05-26 01:47:27 -04:00
: handle-get ( action -- response )
'[
2008-09-10 23:11:40 -04:00
_ dup display>> [
{
[ init>> call( -- ) ]
[ authorize>> call( -- ) ]
[ drop restore-validation-errors ]
[ display>> call( -- response ) ]
} cleave
] [ drop <400> ] if
] with-exit-continuation ;
2008-03-11 04:39:09 -04:00
CONSTANT: revalidate-url-key "__u"
2008-05-27 01:01:57 -04:00
: revalidate-url ( -- url/f )
revalidate-url-key param
2008-09-29 23:33:06 -04:00
dup [ >url ensure-port [ same-host? ] keep and ] when ;
2008-07-10 00:41:45 -04:00
: validation-failed ( -- * )
post-request? revalidate-url and [
begin-conversation
nested-forms-key param " " split harvest nested-forms cset
form get form cset
<continue-conversation>
2008-07-10 00:41:45 -04:00
] [ <400> ] if*
exit-with ;
: handle-post ( action -- response )
'[
2008-09-10 23:11:40 -04:00
_ dup submit>> [
[ validate>> call( -- ) ]
[ authorize>> call( -- ) ]
[ submit>> call( -- response ) ]
tri
] [ drop <400> ] if
] with-exit-continuation ;
: handle-rest ( path action -- )
rest>> dup [ [ "/" join ] dip set-param ] [ 2drop ] if ;
: init-action ( path action -- )
begin-form
handle-rest ;
M: action call-responder* ( path action -- response )
[ init-action ] keep
request get method>> {
{ "GET" [ handle-get ] }
{ "HEAD" [ handle-get ] }
{ "POST" [ handle-post ] }
} case ;
M: action modify-form
drop url get revalidate-url-key hidden-form-field ;
2008-05-26 01:47:27 -04:00
: check-validation ( -- )
2008-07-10 00:41:45 -04:00
validation-failed? [ validation-failed ] when ;
2008-05-26 01:47:27 -04:00
: validate-params ( validators -- )
params get swap validate-values check-validation ;
2008-05-26 01:47:27 -04:00
: validate-integer-id ( -- )
{ { "id" [ v-number ] } } validate-params ;
TUPLE: page-action < action template ;
: <chloe-content> ( path -- response )
resolve-template-path <chloe> <html-content> ;
2008-05-26 01:47:27 -04:00
: <page-action> ( -- page )
page-action new-action
2008-09-10 23:11:40 -04:00
dup '[ _ template>> <chloe-content> ] >>display ;