diff --git a/extra/http/http.factor b/extra/http/http.factor index c25ae5590d..9e31855e53 100755 --- a/extra/http/http.factor +++ b/extra/http/http.factor @@ -394,16 +394,18 @@ body ; [ unparse-cookies "set-cookie" pick set-at ] when* write-header ; -: body>quot ( body -- quot ) - { - { [ dup not ] [ drop [ ] ] } - { [ dup string? ] [ [ write ] curry ] } - { [ dup callable? ] [ ] } - [ [ stdio get stream-copy ] curry ] - } cond ; +GENERIC: write-response-body* ( body -- ) + +M: f write-response-body* drop ; + +M: string write-response-body* write ; + +M: callable write-response-body* call ; + +M: object write-response-body* stdio get stream-copy ; : write-response-body ( response -- response ) - dup body>> body>quot call ; + dup body>> write-response-body* ; M: response write-response ( respose -- ) write-response-version diff --git a/extra/http/server/auth/login/login.factor b/extra/http/server/auth/login/login.factor index 888234cc96..b0cc0c21d1 100755 --- a/extra/http/server/auth/login/login.factor +++ b/extra/http/server/auth/login/login.factor @@ -68,10 +68,7 @@ M: user-saver dispose [ blank-values ] >>init - [ - "text/html" - [ form edit-form ] >>body - ] >>display + [ form edit-form ] >>display [ blank-values @@ -120,10 +117,7 @@ SYMBOL: user-exists? [ blank-values ] >>init - [ - "text/html" - [ form edit-form ] >>body - ] >>display + [ form edit-form ] >>display [ blank-values @@ -174,10 +168,7 @@ SYMBOL: previous-page dup email>> "email" set-value ] >>init - [ - "text/html" - [ form edit-form ] >>body - ] >>display + [ form edit-form ] >>display [ blank-values @@ -262,10 +253,7 @@ SYMBOL: lost-password-from [ blank-values ] >>init - [ - "text/html" - [ form edit-form ] >>body - ] >>display + [ form edit-form ] >>display [ blank-values @@ -314,10 +302,7 @@ SYMBOL: lost-password-from ] H{ } make-assoc values set ] >>init - [ - "text/html" - [ edit-form ] >>body - ] >>display + [ edit-form ] >>display [ blank-values diff --git a/extra/http/server/boilerplate/boilerplate.factor b/extra/http/server/boilerplate/boilerplate.factor index 2bd6eee340..4e847cff70 100644 --- a/extra/http/server/boilerplate/boilerplate.factor +++ b/extra/http/server/boilerplate/boilerplate.factor @@ -2,6 +2,7 @@ ! See http://factorcode.org/license.txt for BSD license. USING: accessors kernel namespaces boxes sequences strings io io.streams.string +http http.server http.server.templating ; IN: http.server.boilerplate @@ -27,6 +28,8 @@ SYMBOL: style : write-style ( -- ) style get >string write ; +SYMBOL: nested-template? + SYMBOL: next-template : call-next-template ( -- ) @@ -39,9 +42,15 @@ M: f call-template drop call-next-template ; title get [ title set ] unless style get [ SBUF" " clone style set ] unless - swap with-string-writer next-template set - - call-template + [ + [ + nested-template? on + write-response-body* + ] with-string-writer + next-template set + ] + [ call-template ] + bi* ] with-scope ; inline M: boilerplate call-responder diff --git a/extra/http/server/components/components-tests.factor b/extra/http/server/components/components-tests.factor index 29cfa1de8b..6d3a048ac4 100755 --- a/extra/http/server/components/components-tests.factor +++ b/extra/http/server/components/components-tests.factor @@ -1,12 +1,10 @@ IN: http.server.components.tests USING: http.server.components http.server.forms http.server.validators namespaces tools.test kernel accessors -tuple-syntax mirrors http.server.actions -http.server.templating.fhtml +tuple-syntax mirrors +http http.server.actions http.server.templating.fhtml io.streams.string io.streams.null ; -\ render-edit must-infer - validation-failed? off [ 3 ] [ "3" "n" validate ] unit-test @@ -65,9 +63,9 @@ TUPLE: test-tuple text number more-text ; "hi" >>default add-field ; -[ ] [ values set view-form ] unit-test +[ ] [ values set view-form write-response-body drop ] unit-test -[ ] [ values set edit-form ] unit-test +[ ] [ values set edit-form write-response-body drop ] unit-test [ TUPLE{ test-tuple number: 123 more-text: "hi" } ] [ from-tuple diff --git a/extra/http/server/components/components.factor b/extra/http/server/components/components.factor index 3ab0bdd770..50353c6b87 100755 --- a/extra/http/server/components/components.factor +++ b/extra/http/server/components/components.factor @@ -7,9 +7,12 @@ continuations math ; IN: http.server.components ! Renderer protocol +GENERIC: render-summary* ( value renderer -- ) GENERIC: render-view* ( value renderer -- ) GENERIC: render-edit* ( value id renderer -- ) +M: object render-summary* render-view* ; + TUPLE: field type ; C: field @@ -235,3 +238,35 @@ TUPLE: text < string ; : ( id -- component ) text new-text ; + +! List components +SYMBOL: +plain+ +SYMBOL: +ordered+ +SYMBOL: +unordered+ + +TUPLE: list-renderer component type ; + +C: list-renderer + +: render-list ( value component -- ) + [ render-summary* ] curry each ; + +: render-ordered-list ( value component -- ) + [
  • render-summary*
  • ] curry each ; + +: render-unordered-list ( value component -- ) + [
  • render-summary*
  • ] curry each ; + +M: list-renderer render-view* + [ component>> ] [ type>> ] bi { + { +plain+ [ render-list ] } + { +ordered+ [
      render-ordered-list
    ] } + { +unordered+ [
      render-unordered-list
    ] } + } case ; + +TUPLE: list < component ; + +: ( id component type -- list ) + list swap new-component ; + +M: list component-string drop ; diff --git a/extra/http/server/crud/crud.factor b/extra/http/server/crud/crud.factor index cf9771e15f..65de881adb 100755 --- a/extra/http/server/crud/crud.factor +++ b/extra/http/server/crud/crud.factor @@ -15,10 +15,7 @@ IN: http.server.crud [ "id" get ctor call select-tuple from-tuple ] >>init - [ - "text/html" - [ form view-form ] >>body - ] >>display ; + [ form view-form ] >>display ; : ( id next -- response ) swap number>string "id" associate ; @@ -36,10 +33,7 @@ IN: http.server.crud if ] >>init - [ - "text/html" - [ form edit-form ] >>body - ] >>display + [ form edit-form ] >>display [ f ctor call from-tuple @@ -65,12 +59,9 @@ IN: http.server.crud :: ( form ctor -- action ) [ - "text/html" - [ - blank-values + blank-values - f ctor call select-tuples "list" set-value + f ctor call select-tuples "list" set-value - form view-form - ] >>body + form view-form ] >>display ; diff --git a/extra/http/server/forms/forms.factor b/extra/http/server/forms/forms.factor index 2c2b673f83..1b4f7f4d37 100644 --- a/extra/http/server/forms/forms.factor +++ b/extra/http/server/forms/forms.factor @@ -1,4 +1,7 @@ +! Copyright (C) 2008 Slava Pestov +! See http://factorcode.org/license.txt for BSD license. USING: kernel accessors assocs namespaces io.files sequences fry +http.server http.server.actions http.server.components http.server.validators @@ -17,8 +20,11 @@ M: form init V{ } clone >>components ; : add-field ( form component -- form ) dup id>> pick components>> set-at ; +: set-components ( form -- ) + components>> components set ; + : with-form ( form quot -- ) - >r components>> components r> with-variable ; inline + [ [ set-components ] [ call ] bi* ] with-scope ; inline : set-defaults ( form -- ) [ @@ -29,14 +35,16 @@ M: form init V{ } clone >>components ; ] assoc-each ] with-form ; -: view-form ( form -- ) - dup view-template>> '[ , call-template ] with-form ; +: ( form template -- response ) + [ components>> components set ] + [ "text/html" swap >>body ] + bi* ; -: edit-form ( form -- ) - dup edit-template>> '[ , call-template ] with-form ; +: view-form ( form -- response ) + dup view-template>> ; -: summary-form ( form -- ) - dup summary-template>> '[ , call-template ] with-form ; +: edit-form ( form -- response ) + dup edit-template>> ; : validate-param ( id component -- ) [ [ params get at ] [ validate ] bi* ] @@ -52,19 +60,19 @@ M: form init V{ } clone >>components ; : validate-form ( form -- ) (validate-form) [ validation-failed ] when ; -! List components -TUPLE: list-renderer form ; +: render-form ( value form template -- ) + [ + [ from-tuple ] + [ set-components ] + [ call-template ] + tri* + ] with-scope ; -C: list-renderer +M: form render-summary* + dup summary-template>> render-form ; -M: list-renderer render-view* - form>> [ - [ >r from-tuple r> summary-form ] with-scope - ] curry each ; +M: form render-view* + dup view-template>> render-form ; -TUPLE: list < component ; - -: ( id form -- list ) - list swap new-component ; - -M: list component-string drop ; +M: form render-edit* + dup edit-template>> render-form ; diff --git a/extra/http/server/templating/chloe/chloe.factor b/extra/http/server/templating/chloe/chloe.factor index 9da153607f..06cf2936ce 100644 --- a/extra/http/server/templating/chloe/chloe.factor +++ b/extra/http/server/templating/chloe/chloe.factor @@ -156,13 +156,19 @@ SYMBOL: tags [ V{ } clone tags set - { - [ xml-prolog write-prolog ] - [ xml-before write-chunk ] - [ process-template ] - [ xml-after write-chunk ] - } cleave + nested-template? get [ + process-template + ] [ + { + [ xml-prolog write-prolog ] + [ xml-before write-chunk ] + [ process-template ] + [ xml-after write-chunk ] + } cleave + ] if ] with-scope ; M: chloe call-template path>> utf8 read-xml process-chloe ; + +INSTANCE: chloe template diff --git a/extra/http/server/templating/fhtml/fhtml.factor b/extra/http/server/templating/fhtml/fhtml.factor index 237931dc34..1cba4b9b2e 100755 --- a/extra/http/server/templating/fhtml/fhtml.factor +++ b/extra/http/server/templating/fhtml/fhtml.factor @@ -94,3 +94,5 @@ M: fhtml call-template ( filename -- ) [ serve-template ] "application/x-factor-server-page" pick special>> set-at ; + +INSTANCE: fhtml template diff --git a/extra/http/server/templating/templating.factor b/extra/http/server/templating/templating.factor index 378823e9d1..f69dd9bfe0 100644 --- a/extra/http/server/templating/templating.factor +++ b/extra/http/server/templating/templating.factor @@ -1,9 +1,13 @@ USING: accessors kernel fry io.encodings.utf8 io.files -http.server ; +http http.server ; IN: http.server.templating +MIXIN: template + GENERIC: call-template ( template -- ) +M: template write-response-body* call-template ; + : template-convert ( template output -- ) utf8 [ call-template ] with-file-writer ; diff --git a/extra/webapps/todo/todo.factor b/extra/webapps/todo/todo.factor index d8d9988109..917b9bf7a7 100755 --- a/extra/webapps/todo/todo.factor +++ b/extra/webapps/todo/todo.factor @@ -53,7 +53,7 @@ todo "TODO" : ( -- form ) "todo-list"
    "todo-list" todo-template >>view-template - "list" + "list" +plain+ add-field ; TUPLE: todo-responder < dispatcher ;