2 USING: embedded generic arrays namespaces prettyprint io
3 sequences words kernel httpd html errors hashtables http
10 : define-action ( word params -- )
11 over t "action" set-word-prop
12 "action-params" set-word-prop ;
14 : define-redirect ( word quot -- )
15 "action-redirect" set-word-prop ;
17 : responder-vocab ( name -- vocab )
18 "furnace:" swap append ;
20 : lookup-action ( name webapp -- word )
21 responder-vocab lookup dup [
22 dup "action" word-prop [ drop f ] unless
25 : current-action ( url -- word/f )
26 dup empty? [ drop default-action get ] when
27 "responder" get lookup-action ;
29 PREDICATE: word action "action" word-prop ;
31 : quot>query ( seq action -- hash )
32 "action-params" word-prop
33 [ first swap 2array ] 2map alist>hash ;
35 : action-link ( query action -- url )
37 "/responder/" % "responder" get % "/" %
39 ] "" make swap build-url ;
41 : action-call? ( args obj -- ? )
42 action? >r [ word? not ] all? r> and ;
44 : quot-link ( quot -- url )
45 1 swap cut* peek 2dup action-call? [
46 [ quot>query ] keep action-link
48 t register-html-callback
51 : render-link ( quot name -- )
52 <a swap quot-link =href a> write </a> ;
54 : query>quot ( params action -- seq )
55 "action-params" word-prop
56 [ dup first rot hash [ ] [ second ] ?if ] map-with ;
58 : perform-redirect ( action -- )
59 "action-redirect" word-prop [ quot-link redirect ] when* ;
61 : call-action ( params action -- )
62 [ query>quot ] keep [ add >quotation call ] keep
65 : service-request ( url params -- )
67 [ call-action ] [ <pre> print-error </pre> ] recover
69 "404 no such action: " "argument" get append httpd-error
72 : service-get ( url -- ) "query" get swap service-request ;
74 : service-post ( url -- ) "response" get swap service-request ;
76 : explode-tuple ( tuple -- )
77 dup tuple>array 2 tail swap class "slot-names" word-prop
80 : call-template ( model template -- )
82 >r [ explode-tuple ] when* r>
83 ".fhtml" append resource-path run-embedded-file
86 TUPLE: component model template ;
88 TUPLE: page title root ;
90 C: page ( title model template -- page )
91 [ >r <component> r> set-page-root ] keep
92 [ set-page-title ] keep ;
94 : render-template ( model template -- )
95 template-path get swap path+ call-template ;
98 dup component-model swap component-template
101 : render-page ( title model template -- )
103 <page> "contrib/furnace/page" call-template ;
105 : web-app ( name default path -- )
106 over responder-vocab create-vocab drop
111 [ service-get ] "get" set
112 [ service-post ] "post" set
113 ! [ service-head ] "head" set