]> gitweb.factorcode.org Git - factor.git/commitdiff
New html.forms abstraction fixes some problems; clean up some code
authorSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Sun, 15 Jun 2008 07:38:12 +0000 (02:38 -0500)
committerSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Sun, 15 Jun 2008 07:38:12 +0000 (02:38 -0500)
19 files changed:
extra/furnace/actions/actions.factor
extra/furnace/auth/login/login.factor
extra/furnace/flash/flash.factor
extra/furnace/furnace.factor
extra/html/components/components-tests.factor
extra/html/components/components.factor
extra/html/forms/forms-tests.factor [new file with mode: 0644]
extra/html/forms/forms.factor [new file with mode: 0644]
extra/html/templates/chloe/chloe-tests.factor
extra/html/templates/chloe/chloe.factor
extra/http/http-tests.factor
extra/validators/validators-tests.factor
extra/validators/validators.factor
extra/webapps/blogs/blogs.factor
extra/webapps/pastebin/pastebin.factor
extra/webapps/planet/planet.factor
extra/webapps/todo/todo.factor
extra/webapps/user-admin/edit-user.xml
extra/webapps/user-admin/user-admin.factor

index 9cc1880cc32fd9435b3a92cb9e05dd15a85d9d7d..4b431c83bca65450c0bbdb83cffc5349d7839ba2 100755 (executable)
@@ -8,6 +8,7 @@ http.server
 http.server.responses\r
 furnace\r
 furnace.flash\r
+html.forms\r
 html.elements\r
 html.components\r
 html.components\r
@@ -20,10 +21,10 @@ SYMBOL: params
 SYMBOL: rest\r
 \r
 : render-validation-messages ( -- )\r
-    validation-messages get\r
+    form get errors>>\r
     dup empty? [ drop ] [\r
         <ul "errors" =class ul>\r
-            [ <li> message>> escape-string write </li> ] each\r
+            [ <li> escape-string write </li> ] each\r
         </ul>\r
     ] if ;\r
 \r
@@ -37,8 +38,21 @@ TUPLE: action rest authorize init display validate submit ;
 : <action> ( -- action )\r
     action new-action ;\r
 \r
-: flashed-variables ( -- seq )\r
-    { validation-messages named-validation-messages } ;\r
+: set-nested-form ( form name -- )\r
+    dup empty? [\r
+        drop form set\r
+    ] [\r
+        dup length 1 = [\r
+            first set-value\r
+        ] [\r
+            unclip [ set-nested-form ] nest-form\r
+        ] if\r
+    ] if ;\r
+\r
+: restore-validation-errors ( -- )\r
+    form fget [\r
+        nested-forms fget set-nested-form\r
+    ] when* ;\r
 \r
 : handle-get ( action -- response )\r
     '[\r
@@ -46,25 +60,12 @@ TUPLE: action rest authorize init display validate submit ;
             {\r
                 [ init>> call ]\r
                 [ authorize>> call ]\r
-                [ drop flashed-variables restore-flash ]\r
+                [ drop restore-validation-errors ]\r
                 [ display>> call ]\r
             } cleave\r
         ] [ drop <400> ] if\r
     ] with-exit-continuation ;\r
 \r
-: validation-failed ( -- * )\r
-    post-request? [ f ] [ <400> ] if exit-with ;\r
-\r
-: (handle-post) ( action -- response )\r
-    '[\r
-        , dup submit>> [\r
-            [ validate>> call ]\r
-            [ authorize>> call ]\r
-            [ submit>> call ]\r
-            tri\r
-        ] [ drop <400> ] if\r
-    ] with-exit-continuation ;\r
-\r
 : param ( name -- value )\r
     params get at ;\r
 \r
@@ -74,24 +75,29 @@ TUPLE: action rest authorize init display validate submit ;
     revalidate-url-key param\r
     dup [ >url [ same-host? ] keep and ] when ;\r
 \r
+: validation-failed ( -- * )\r
+    post-request? revalidate-url and\r
+    [\r
+        nested-forms-key param " " split harvest nested-forms set\r
+        { form nested-forms } <flash-redirect>\r
+    ] [ <400> ] if*\r
+    exit-with ;\r
+\r
 : handle-post ( action -- response )\r
     '[\r
-        form-nesting-key params get at " " split harvest\r
-        [ , (handle-post) ]\r
-        [ swap '[ , , nest-values ] ] reduce\r
-        call\r
-    ] with-exit-continuation\r
-    [\r
-        revalidate-url\r
-        [ flashed-variables <flash-redirect> ] [ <403> ] if*\r
-    ] unless* ;\r
+        , dup submit>> [\r
+            [ validate>> call ]\r
+            [ authorize>> call ]\r
+            [ submit>> call ]\r
+            tri\r
+        ] [ drop <400> ] if\r
+    ] with-exit-continuation ;\r
 \r
 : handle-rest ( path action -- assoc )\r
     rest>> dup [ [ "/" join ] dip associate ] [ 2drop f ] if ;\r
 \r
 : init-action ( path action -- )\r
-    blank-values\r
-    init-validation\r
+    begin-form\r
     handle-rest\r
     request get request-params assoc-union params set ;\r
 \r
@@ -110,8 +116,7 @@ M: action modify-form
     validation-failed? [ validation-failed ] when ;\r
 \r
 : validate-params ( validators -- )\r
-    params get swap validate-values from-object\r
-    check-validation ;\r
+    params get swap validate-values check-validation ;\r
 \r
 : validate-integer-id ( -- )\r
     { { "id" [ v-number ] } } validate-params ;\r
index a1d2bf47c38c64fb95f3da6452ed7e1f277751ae..80005c452aff2b164d2ee003f4683b2d73ca69d0 100755 (executable)
@@ -13,6 +13,7 @@ destructors
 checksums\r
 checksums.sha2\r
 validators\r
+html.forms\r
 html.components\r
 html.elements\r
 urls\r
@@ -34,13 +35,16 @@ QUALIFIED: smtp
 IN: furnace.auth.login\r
 \r
 : word>string ( word -- string )\r
-    [ word-vocabulary ] [ drop ":" ] [ word-name ] tri 3append ;\r
+    [ word-vocabulary ] [ word-name ] bi ":" swap 3append ;\r
 \r
 : words>strings ( seq -- seq' )\r
     [ word>string ] map ;\r
 \r
+ERROR: no-such-word name vocab ;\r
+\r
 : string>word ( string -- word )\r
-    ":" split1 swap lookup ;\r
+    ":" split1 swap 2dup lookup dup\r
+    [ 2nip ] [ drop no-such-word ] if ;\r
 \r
 : strings>words ( seq -- seq' )\r
     [ string>word ] map ;\r
index 43e0d293a5a82415315415555a133ac456d35ac0..e06cdac09093535da643ca3c84717790403220fe 100644 (file)
@@ -25,7 +25,9 @@ TUPLE: flash-scopes < server-state-manager ;
 
 SYMBOL: flash-scope
 
-: fget ( key -- value ) flash-scope get at ;
+: fget ( key -- value )
+    flash-scope get dup
+    [ namespace>> at ] [ 2drop f ] if ;
 
 : get-flash-scope ( id -- flash-scope )
     dup [ flash-scope get-state ] when
index a51841d4ad8098e3385860e98483b173fa5705b1..e9d1b29da8af449547c1a574903401fcc4cefe10 100644 (file)
@@ -10,6 +10,7 @@ xml.entities
 xml.writer
 html.components
 html.elements
+html.forms
 html.templates
 html.templates.chloe
 html.templates.chloe.syntax
@@ -154,11 +155,11 @@ CHLOE: a
         input/>
     ] [ 2drop ] if ;
 
-: form-nesting-key "__n" ;
+: nested-forms-key "__n" ;
 
 : form-magic ( tag -- )
     [ modify-form ] each-responder
-    nested-values get " " join f like form-nesting-key hidden-form-field
+    nested-forms get " " join f like nested-forms-key hidden-form-field
     "for" optional-attr [ "," split [ hidden render ] each ] when* ;
 
 : form-start-tag ( tag -- )
index 8ec3a58611d3241d58ceebdfbc9869c5c03a8b32..5779371078b7471de8aa93f4a3736ad45b7b5e8e 100644 (file)
@@ -1,9 +1,9 @@
 IN: html.components.tests
 USING: tools.test kernel io.streams.string
 io.streams.null accessors inspector html.streams
-html.elements html.components namespaces ;
+html.elements html.components html.forms namespaces ;
 
-[ ] [ blank-values ] unit-test
+[ ] [ begin-form ] unit-test
 
 [ ] [ 3 "hi" set-value ] unit-test
 
@@ -63,7 +63,7 @@ TUPLE: color red green blue ;
     ] with-null-writer
 ] unit-test
 
-[ ] [ blank-values ] unit-test
+[ ] [ begin-form ] unit-test
 
 [ ] [ "new york" "city1" set-value ] unit-test
 
@@ -101,7 +101,7 @@ TUPLE: color red green blue ;
     ] with-null-writer
 ] unit-test
 
-[ ] [ blank-values ] unit-test
+[ ] [ begin-form ] unit-test
 
 [ ] [ t "delivery" set-value ] unit-test
 
@@ -167,12 +167,19 @@ M: link-test link-href drop "http://www.apple.com/foo&bar" ;
     =
 ] unit-test
 
-[ ] [ blank-values ] unit-test
+[ ] [ begin-form ] unit-test
 
 [ ] [
     "factor" [
         "concatenative" "model" set-value
-    ] nest-values
+    ] nest-form
 ] unit-test
 
-[ H{ { "factor" H{ { "model" "concatenative" } } } } ] [ values get ] unit-test
+[
+    H{
+        {
+            "factor"
+            T{ form f V{ } H{ { "model" "concatenative" } } }
+        }
+    }
+] [ values ] unit-test
index 7355cd153d2173df1b3b0ab136dac946b851ee30..b6b7f22b1daccb91fe9b58ae73fc4eaa8ea86fc7 100644 (file)
@@ -1,85 +1,26 @@
 ! Copyright (C) 2008 Slava Pestov
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors kernel namespaces io math.parser assocs classes
-classes.tuple words arrays sequences sequences.lib splitting
-mirrors hashtables combinators continuations math strings
-fry locals calendar calendar.format xml.entities validators
-html.elements html.streams xmode.code2html farkup inspector
-lcs.diff2html urls present ;
+classes.tuple words arrays sequences splitting mirrors
+hashtables combinators continuations math strings inspector
+fry locals calendar calendar.format xml.entities
+validators urls present
+xmode.code2html lcs.diff2html farkup
+html.elements html.streams html.forms ;
 IN: html.components
 
-SYMBOL: values
-
-: check-value-name ( name -- name )
-    dup string? [ "Value name not a string" throw ] unless ;
-
-: value ( name -- value ) check-value-name values get at ;
-
-: set-value ( value name -- ) check-value-name values get set-at ;
-
-: blank-values ( -- ) H{ } clone values set ;
-
-: prepare-value ( name object -- value name object )
-    [ [ value ] keep ] dip ; inline
-
-: from-object ( object -- )
-    dup assoc? [ <mirror> ] unless
-    values get swap update ;
-
-: deposit-values ( destination names -- )
-    [ dup value ] H{ } map>assoc update ;
-
-: deposit-slots ( destination names -- )
-    [ <mirror> ] dip deposit-values ;
-
-: with-each-value ( name quot -- )
-    [ value ] dip '[
-        [
-            values [ clone ] change
-            1+ "index" set-value
-            "value" set-value
-            @
-        ] with-scope
-    ] each-index ; inline
-
-: with-each-object ( name quot -- )
-    [ value ] dip '[
-        [
-            blank-values
-            1+ "index" set-value
-            from-object
-            @
-        ] with-scope
-    ] each-index ; inline
-
-SYMBOL: nested-values
-
-: with-values ( name quot -- )
-    '[
-        ,
-        [ nested-values [ swap prefix ] change ]
-        [ value blank-values from-object ]
-        bi
-        @
-    ] with-scope ; inline
-
-: nest-values ( name quot -- )
-    swap [
-        [
-            H{ } clone [ values set call ] keep
-        ] with-scope
-    ] dip set-value ; inline
-
 GENERIC: render* ( value name render -- )
 
 : render ( name renderer -- )
-    over named-validation-messages get at [
-        [ value>> ] [ message>> ] bi
-        [ -rot render* ] dip
-        render-error
-    ] [
-        prepare-value render*
-    ] if* ;
+    prepare-value
+    [
+        dup validation-error?
+        [ [ message>> ] [ value>> ] bi ]
+        [ f swap ]
+        if
+    ] 2dip
+    render*
+    [ render-error ] when* ;
 
 <PRIVATE
 
diff --git a/extra/html/forms/forms-tests.factor b/extra/html/forms/forms-tests.factor
new file mode 100644 (file)
index 0000000..d2dc3ed
--- /dev/null
@@ -0,0 +1,67 @@
+IN: html.forms.tests
+USING: kernel sequences tools.test assocs html.forms validators accessors
+namespaces ;
+
+: with-validation ( quot -- messages )
+    [
+        begin-form
+        call
+    ] with-scope ; inline
+
+[ 14 ] [
+    [
+        "14" [ v-number 13 v-min-value 100 v-max-value ] validate
+    ] with-validation
+] unit-test
+
+[ t ] [
+    [
+        "140" [ v-number 13 v-min-value 100 v-max-value ] validate
+        [ validation-error? ]
+        [ value>> "140" = ]
+        bi and
+    ] with-validation
+] unit-test
+
+TUPLE: person name age ;
+
+person {
+    { "name" [ ] }
+    { "age" [ v-number 13 v-min-value 100 v-max-value ] }
+} define-validators
+
+[ t t ] [
+    [
+        { { "age" "" } }
+        { { "age" [ v-required ] } }
+        validate-values
+        validation-failed?
+        "age" value
+        [ validation-error? ]
+        [ message>> "required" = ]
+        bi and
+    ] with-validation
+] unit-test
+
+[ H{ { "a" 123 } } f ] [
+    [
+        H{
+            { "a" "123" }
+            { "b" "c" }
+            { "c" "d" }
+        }
+        H{
+            { "a" [ v-integer ] }
+        } validate-values
+        values
+        validation-failed?
+    ] with-validation
+] unit-test
+
+[ t "foo" ] [
+    [
+        "foo" validation-error
+        validation-failed?
+        form get errors>> first
+    ] with-validation
+] unit-test
diff --git a/extra/html/forms/forms.factor b/extra/html/forms/forms.factor
new file mode 100644 (file)
index 0000000..0da3fcb
--- /dev/null
@@ -0,0 +1,106 @@
+! Copyright (C) 2008 Slava Pestov
+! See http://factorcode.org/license.txt for BSD license.
+USING: kernel accessors strings namespaces assocs hashtables
+mirrors math fry sequences sequences.lib words continuations ;
+IN: html.forms
+
+TUPLE: form errors values validation-failed ;
+
+: <form> ( -- form )
+    form new
+        V{ } clone >>errors
+        H{ } clone >>values ;
+
+M: form clone
+    call-next-method
+        [ clone ] change-errors
+        [ clone ] change-values ;
+
+: check-value-name ( name -- name )
+    dup string? [ "Value name not a string" throw ] unless ;
+
+: values ( -- assoc )
+    form get values>> ;
+
+: value ( name -- value )
+    check-value-name values at ;
+
+: set-value ( value name -- )
+    check-value-name values set-at ;
+
+: begin-form ( -- ) <form> form set ;
+
+: prepare-value ( name object -- value name object )
+    [ [ value ] keep ] dip ; inline
+
+: from-object ( object -- )
+    [ values ] [ make-mirror ] bi* update ;
+
+: to-object ( destination names -- )
+    [ make-mirror ] [ values extract-keys ] bi* update ;
+
+: with-each-value ( name quot -- )
+    [ value ] dip '[
+        [
+            form [ clone ] change
+            1+ "index" set-value
+            "value" set-value
+            @
+        ] with-scope
+    ] each-index ; inline
+
+: with-each-object ( name quot -- )
+    [ value ] dip '[
+        [
+            begin-form
+            1+ "index" set-value
+            from-object
+            @
+        ] with-scope
+    ] each-index ; inline
+
+SYMBOL: nested-forms
+
+: with-form ( name quot -- )
+    '[
+        ,
+        [ nested-forms [ swap prefix ] change ]
+        [ value form set ]
+        bi
+        @
+    ] with-scope ; inline
+
+: nest-form ( name quot -- )
+    swap [
+        [
+            <form> form set
+            call
+            form get
+        ] with-scope
+    ] dip set-value ; inline
+
+TUPLE: validation-error value message ;
+
+C: <validation-error> validation-error
+
+: validation-error ( message -- )
+    form get
+    t >>validation-failed
+    errors>> push ;
+
+: validation-failed? ( -- ? )
+    form get validation-failed>> ;
+
+: define-validators ( class validators -- )
+    >hashtable "validators" set-word-prop ;
+
+: validate ( value quot -- result )
+    [ <validation-error> ] recover ; inline
+
+: validate-value ( name value quot -- )
+    validate
+    dup validation-error? [ form get t >>validation-failed drop ] when
+    swap set-value ;
+
+: validate-values ( assoc validators -- assoc' )
+    swap '[ dup , at _ validate-value ] assoc-each ;
index 433aedbc9a88717ffc307abacd211f7fde5b7251..87ba37ed9ecc52ccf650977f8cf2b037a35f9701 100644 (file)
@@ -9,13 +9,13 @@ IN: html.templates.chloe.tests
 [ f ] [ "" parse-query-attr ] unit-test
 
 [ H{ { "a" "b" } } ] [
-    blank-values
+    begin-form
     "b" "a" set-value
     "a" parse-query-attr
 ] unit-test
 
 [ H{ { "a" "b" } { "c" "d" } } ] [
-    blank-values
+    begin-form
     "b" "a" set-value
     "d" "c" set-value
     "a,c" parse-query-attr
@@ -69,7 +69,7 @@ IN: html.templates.chloe.tests
     ] run-template
 ] unit-test
 
-[ ] [ blank-values ] unit-test
+[ ] [ begin-form ] unit-test
 
 [ ] [ "A label" "label" set-value ] unit-test
 
@@ -157,7 +157,7 @@ TUPLE: person first-name last-name ;
     ] run-template
 ] unit-test
 
-[ ] [ blank-values ] unit-test
+[ ] [ begin-form ] unit-test
 
 [ ] [
     H{ { "first-name" "RBaxter" } { "last-name" "Unknown" } } "person" set-value
@@ -170,7 +170,7 @@ TUPLE: person first-name last-name ;
 ] unit-test
 
 [ ] [
-    blank-values
+    begin-form
     { "a" "b" } "choices" set-value
     "true" "b" set-value
 ] unit-test
index 936c06ae7edeedcc5739a60736a566e31804cd0c..32fe954178dce05c94159f2e1c3e0dcb61a7b395 100644 (file)
@@ -5,6 +5,7 @@ classes.tuple assocs splitting words arrays memoize
 io io.files io.encodings.utf8 io.streams.string
 unicode.case tuple-syntax mirrors fry math urls present
 multiline xml xml.data xml.writer xml.utilities
+html.forms
 html.elements
 html.components
 html.templates
@@ -76,7 +77,7 @@ CHLOE: each [ with-each-value ] (bind-tag) ;
 
 CHLOE: bind-each [ with-each-object ] (bind-tag) ;
 
-CHLOE: bind [ with-values ] (bind-tag) ;
+CHLOE: bind [ with-form ] (bind-tag) ;
 
 : error-message-tag ( tag -- )
     children>string render-error ;
index bc206f08b7c86587ea73a49a323d4d8c621af2fd..88d42d9796c31415f7b7c2e0626022dabcbf1e44 100755 (executable)
@@ -223,7 +223,8 @@ test-db [
 
 [ "Goodbye" ] [ "http://localhost:1237/quit" http-get nip ] unit-test
 
-USING: html.components html.elements xml xml.utilities validators
+USING: html.components html.elements html.forms
+xml xml.utilities validators
 furnace furnace.flash ;
 
 SYMBOL: a
index 7d4325cbb6644acc8706bad548c910836aa66561..bd24323f20ebc0c0c73651422f16db0bd5e9e33c 100644 (file)
@@ -2,14 +2,6 @@ IN: validators.tests
 USING: kernel sequences tools.test validators accessors
 namespaces assocs ;
 
-: with-validation ( quot -- messages )
-    [
-        init-validation
-        call
-        validation-messages get
-        named-validation-messages get >alist append
-    ] with-scope ; inline
-
 [ "" v-one-line ] must-fail
 [ "hello world" ] [ "hello world" v-one-line ] unit-test
 [ "hello\nworld" v-one-line ] must-fail
@@ -60,59 +52,3 @@ namespaces assocs ;
 [ "4561_2612_1234_5467" v-credit-card ] must-fail
 
 [ "4561-2621-1234-5467" v-credit-card ] must-fail
-
-
-[ 14 V{ } ] [
-    [
-        "14" "age" [ v-number 13 v-min-value 100 v-max-value ] validate
-    ] with-validation
-] unit-test
-
-[ f t ] [
-    [
-        "140" "age" [ v-number 13 v-min-value 100 v-max-value ] validate
-    ] with-validation first
-    [ first "age" = ]
-    [ second validation-error? ]
-    [ second value>> "140" = ]
-    tri and and
-] unit-test
-
-TUPLE: person name age ;
-
-person {
-    { "name" [ ] }
-    { "age" [ v-number 13 v-min-value 100 v-max-value ] }
-} define-validators
-
-[ t t ] [
-    [
-        { { "age" "" } } required-values
-        validation-failed?
-    ] with-validation first
-    [ first "age" = ]
-    [ second validation-error? ]
-    [ second message>> "required" = ]
-    tri and and
-] unit-test
-
-[ H{ { "a" 123 } } f V{ } ] [
-    [
-        H{
-            { "a" "123" }
-            { "b" "c" }
-            { "c" "d" }
-        }
-        H{
-            { "a" [ v-integer ] }
-        } validate-values
-        validation-failed?
-    ] with-validation
-] unit-test
-
-[ t "foo" ] [
-    [
-        "foo" validation-error
-        validation-failed?
-    ] with-validation first message>>
-] unit-test
index aeb2dc2f802ece84336816685298e256797db2e3..37c0216740c75752dd5a6a17baf061b5db5571a9 100644 (file)
@@ -1,8 +1,8 @@
 ! Copyright (C) 2006, 2008 Slava Pestov
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel continuations sequences sequences.lib math
-namespaces sets math.parser math.ranges assocs regexp fry
-unicode.categories arrays hashtables words combinators mirrors
+namespaces sets math.parser math.ranges assocs regexp
+unicode.categories arrays hashtables words
 classes quotations xmode.catalog ;
 IN: validators
 
@@ -107,53 +107,3 @@ IN: validators
     ] [
         "invalid credit card number format" throw
     ] if ;
-
-SYMBOL: validation-messages
-SYMBOL: named-validation-messages
-
-: init-validation ( -- )
-    V{ } clone validation-messages set
-    H{ } clone named-validation-messages set ;
-
-: (validation-message) ( obj -- )
-    validation-messages get push ;
-
-: (validation-message-for) ( obj name -- )
-    named-validation-messages get set-at ;
-
-TUPLE: validation-message message ;
-
-C: <validation-message> validation-message
-
-: validation-message ( string -- )
-    <validation-message> (validation-message) ;
-
-: validation-message-for ( string name -- )
-    [ <validation-message> ] dip (validation-message-for) ;
-
-TUPLE: validation-error message value ;
-
-C: <validation-error> validation-error
-
-: validation-error ( message -- )
-    f <validation-error> (validation-message) ;
-
-: validation-error-for ( message value name -- )
-    [ <validation-error> ] dip (validation-message-for) ;
-
-: validation-failed? ( -- ? )
-    validation-messages get [ validation-error? ] contains?
-    named-validation-messages get [ nip validation-error? ] assoc-contains?
-    or ;
-
-: define-validators ( class validators -- )
-    >hashtable "validators" set-word-prop ;
-
-: validate ( value name quot -- result )
-    '[ drop @ ] [ -rot validation-error-for f ] recover ; inline
-
-: required-values ( assoc -- )
-    [ swap [ v-required ] validate drop ] assoc-each ;
-
-: validate-values ( assoc validators -- assoc' )
-    swap '[ [ [ dup , at ] keep ] dip validate ] assoc-map ;
index d0c651c71fab517cedc7b415c024d479b08eaee3..760951eec6ba8aa6f28d35b13700aacecdd1fee8 100644 (file)
@@ -1,8 +1,10 @@
 ! Copyright (C) 2008 Slava Pestov
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel accessors sequences sorting math.order math.parser
-urls validators html.components db db.types db.tuples calendar
-present http.server.dispatchers
+urls validators db db.types db.tuples calendar present
+html.forms
+html.components
+http.server.dispatchers
 furnace
 furnace.actions
 furnace.auth
@@ -142,7 +144,7 @@ M: comment entity-url
             "id" value
             "new-comment" [
                 "parent" set-value
-            ] nest-values
+            ] nest-form
         ] >>init
 
         { blogs "view-post" } >>template ;
@@ -163,7 +165,7 @@ M: comment entity-url
 
         [
             f <post>
-                dup { "title" "content" } deposit-slots
+                dup { "title" "content" } to-object
                 uid >>author
                 now >>date
             [ insert-tuple ] [ entity-url <redirect> ] bi
@@ -195,7 +197,7 @@ M: comment entity-url
 
         [
             "id" value <post>
-            dup { "title" "author" "date" "content" } deposit-slots
+            dup { "title" "author" "date" "content" } to-object
             [ update-tuple ] [ entity-url <redirect> ] bi
         ] >>submit
 
index d381adafcd234b8235dceea8087e27e45fa3c78d..251872d1ac6248a8d1512302a4de92fa3569ffe8 100644 (file)
@@ -4,6 +4,7 @@ USING: namespaces assocs sorting sequences kernel accessors
 hashtables sequences.lib db.types db.tuples db combinators
 calendar calendar.format math.parser syndication urls xml.writer
 xmode.catalog validators
+html.forms
 html.components
 html.templates.chloe
 http.server
@@ -126,7 +127,7 @@ M: annotation entity-url
                 "parent" set-value
                 mode-names "modes" set-value
                 "factor" "mode" set-value
-            ] nest-values
+            ] nest-form
         ] >>init
 
         { pastebin "paste" } >>template ;
@@ -149,7 +150,7 @@ M: annotation entity-url
 
 : deposit-entity-slots ( tuple -- )
     now >>date
-    { "summary" "author" "mode" "contents" } deposit-slots ;
+    { "summary" "author" "mode" "contents" } to-object ;
 
 : <new-paste-action> ( -- action )
     <page-action>
@@ -160,11 +161,12 @@ M: annotation entity-url
 
         { pastebin "new-paste" } >>template
 
-        [ mode-names "modes" set-value ] >>validate
-
         [
+            mode-names "modes" set-value
             validate-entity
+        ] >>validate
 
+        [
             f <paste>
             [ deposit-entity-slots ]
             [ insert-tuple ]
@@ -196,6 +198,7 @@ M: annotation entity-url
 : <new-annotation-action> ( -- action )
     <action>
         [
+            mode-names "modes" set-value
             { { "parent" [ v-integer ] } } validate-params
             validate-entity
         ] >>validate
index 90b2411fc1f146fa936fc0809475582959f20ad5..b472881e73613bab6069c3ec888f73ddbe89c133 100755 (executable)
@@ -3,9 +3,9 @@
 USING: kernel accessors sequences sorting math math.order
 calendar alarms logging concurrency.combinators namespaces
 sequences.lib db.types db.tuples db fry locals hashtables
+syndication urls xml.writer validators
+html.forms
 html.components
-syndication urls xml.writer
-validators
 http.server
 http.server.dispatchers
 furnace
@@ -130,7 +130,7 @@ posting "POSTINGS"
     } validate-params ;
 
 : deposit-blog-slots ( blog -- )
-    { "name" "www-url" "feed-url" } deposit-slots ;
+    { "name" "www-url" "feed-url" } to-object ;
 
 : <new-blog-action> ( -- action )
     <page-action>
index 077076575435c3ff7bf5a2bedb86a28335d82ddc..dba10184f462f984315e3604a1b00daa31994959 100755 (executable)
@@ -2,6 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors kernel sequences namespaces
 db db.types db.tuples validators hashtables urls
+html.forms
 html.components
 html.templates.chloe
 http.server
@@ -62,7 +63,7 @@ todo "TODO"
 
         [
             f <todo>
-                dup { "summary" "priority" "description" } deposit-slots
+                dup { "summary" "priority" "description" } to-object
             [ insert-tuple ] [ id>> view-todo-url <redirect> ] bi
         ] >>submit ;
 
@@ -82,7 +83,7 @@ todo "TODO"
 
         [
             f <todo>
-                dup { "id" "summary" "priority" "description" } deposit-slots
+                dup { "id" "summary" "priority" "description" } to-object
             [ update-tuple ] [ id>> view-todo-url <redirect> ] bi
         ] >>submit ;
 
index 0c55f8ca76dbe8bceb1b0f297063cd85e662161e..252667462bd844b4e11065d10263aa62809f19c9 100644 (file)
        </table>
        
        <p>
-               <button type="submit" class="link-button link">Update</button>
+               <button type="submit" >Update</button>
                <t:validation-messages />
        </p>
 
        </t:form>
 
-       <t:button t:action="$user-admin/delete" t:for="username" class="link-button link">Delete</t:button>
+       <t:button t:action="$user-admin/delete" t:for="username">Delete</t:button>
 </t:chloe>
index 19153e13541b7d41ca25859a4987e708555f6f2a..5859d616ee19fc4428a317001eb6f05a8106b6df 100644 (file)
@@ -2,6 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel sequences accessors namespaces combinators words
 assocs db.tuples arrays splitting strings validators urls
+html.forms
 html.elements
 html.components
 furnace
@@ -26,10 +27,19 @@ TUPLE: user-admin < dispatcher ;
 : init-capabilities ( -- )
     capabilities get words>strings "capabilities" set-value ;
 
-: selected-capabilities ( -- seq )
+: validate-capabilities ( -- )
     "capabilities" value
-    [ param empty? not ] filter
-    [ string>word ] map ;
+    [ [ param empty? not ] keep set-value ] each ;
+
+: selected-capabilities ( -- seq )
+    "capabilities" value [ value ] filter [ string>word ] map ;
+
+: validate-user ( -- )
+    {
+        { "username" [ v-username ] }
+        { "realname" [ [ v-one-line ] v-optional ] }
+        { "email" [ [ v-email ] v-optional ] }
+    } validate-params ;
 
 : <new-user-action> ( -- action )
     <page-action>
@@ -42,14 +52,13 @@ TUPLE: user-admin < dispatcher ;
 
         [
             init-capabilities
+            validate-capabilities
+
+            validate-user
 
             {
-                { "username" [ v-username ] }
-                { "realname" [ v-one-line ] }
                 { "new-password" [ v-password ] }
                 { "verify-password" [ v-password ] }
-                { "email" [ [ v-email ] v-optional ] }
-                { "capabilities" [ ] }
             } validate-params
 
             same-password-twice
@@ -74,14 +83,16 @@ TUPLE: user-admin < dispatcher ;
 : validate-username ( -- )
     { { "username" [ v-username ] } } validate-params ;
 
+: select-capabilities ( seq -- )
+    [ t swap word>string set-value ] each ;
+
 : <edit-user-action> ( -- action )
     <page-action>
         [
             validate-username
 
             "username" value <user> select-tuple
-            [ from-object ]
-            [ capabilities>> [ "true" swap word>string set-value ] each ] bi
+            [ from-object ] [ capabilities>> select-capabilities ] bi
 
             init-capabilities
         ] >>init
@@ -89,14 +100,17 @@ TUPLE: user-admin < dispatcher ;
         { user-admin "edit-user" } >>template
 
         [
+            "username" value <user> select-tuple
+            [ from-object ] [ capabilities>> select-capabilities ] bi
+
             init-capabilities
+            validate-capabilities
+
+            validate-user
 
             {
-                { "username" [ v-username ] }
-                { "realname" [ v-one-line ] }
                 { "new-password" [ [ v-password ] v-optional ] }
                 { "verify-password" [ [ v-password ] v-optional ] }
-                { "email" [ [ v-email ] v-optional ] }
             } validate-params
 
             "new-password" "verify-password"