Re: [racket-users] How to build new formlets that allow passing default values (such as hidden)?
I get that I need formlet-process somewhere, but what I wanted is to only know about it in the same function/closure where I am doing the rendering - which obviously works in the definition of embed-formlet above, since it embeds the url to format-process. I thought that embed-formlet would somehow store formlet-process in some table somewhere and then make it available in some shape once the URL gets hit, but now I see it's a simple closure. What I want to achieve seems to be done by the following code: (define (debrief request) (define test-formlet (formlet (div "Name:" ,{input-string . => . name}) (list name))) (define (response-generator embed/url) (html-wrapper `((h1 "Testing Formlets") ,(embed-formlet embed/url test-formlet) ))) (define (testing result) (html-wrapper `((h1 "Result") (div ,(first result) (testing (send/suspend/dispatch response-generator))) with the exception that I want a submit button inside the form element, but that should be easy enough to solve. In short, I wanted to have the function `testing` to not need to be passed the formlet I defined, yet to receive the results. Thanks for solving the problem I had, if not the problem I stated. Cheers, Marc On Wed, Aug 23, 2017 at 3:39 PM, Jay McCarthy wrote: > On Wed, Aug 23, 2017 at 8:26 AM, Marc Kaufmann > wrote: > > Hi again, > > > > I am now trying to deal with formlets in a more principled fashion and > thus > > trying to implement, as Philip suggested, to use `send/formlet` and > > `embed-formlet`. After a lot of tinkering, I still haven't figured out > how > > to actually process the formlet (without having to pass it around) with > > embed-formlet. Here is the current example: > > > > (define (debrief request) > > (define test-formlet > > (formlet > > (div "Name:" ,{input-string . => . name}) > > (list name))) > > (define (response-generator embed/url) > > (html-wrapper > > `((h1 "Testing Formlets") > > (form ([action ,(embed/url testing)] > >[method "POST"]) > > (p "Here is the displayed formlet") > > ;,@(formlet-display test-formlet) ;; THIS WORKS > > ,(embed-formlet embed/url test-formlet) > > (input ([type "submit"])) > > > > > > The above works without `embed-formlet` with the following definition of > > `testing`: > > > > (define (testing request) > > (define result (formlet-process test-formlet request)) > > (html-wrapper > > `((h1 "Result") > > (div > > ,(first result) > > (send/suspend/dispatch response-generator)) > > > > But it does not work (or I can't figure out how it works) with > > embed-formlet. How do I process the formlet, with the requirement that I > do > > not want to refer explicitly to `test-formlet`? > > That is not possible. A formlet defines two things: the rendering and > the processing, so it doesn't make sense to process without the > processing definition. > > > Or is this not possible - in > > which case, what does `embed-formlet` do that `formlet-processing` > doesn't? > > Any working example with embed-formlet is appreciate, even if it is not > the > > same as mine. > > When you use embed-formlet, the formlet is displayed and when you > submit, then the formlet's processing runs and returns to the > call-site of send/suspend/dispatch. So you don't separate them. > embed-formlet is really simple: > > (define (embed-formlet embed/url f) > `(form ([action ,(embed/url > (lambda (r) > (formlet-process f r)))]) > ,@(formlet-display f))) > > > Thanks, > > Marc > > > > > > On Thu, Mar 16, 2017 at 2:11 PM, Marc Kaufmann < > marc.kaufman...@gmail.com> > > wrote: > >> > >> Thanks Philip. I checked out the links, but I fear that it's over my > head, > >> and that I would almost surely screw it up. For now I'll keep passing > the > >> parameters. > >> > >> Cheers, > >> Marc > >> > >> On Tuesday, March 14, 2017 at 3:22:39 PM UTC-4, Philip McGrath wrote: > >> > If you want it to be part of the continuation without having to pass > it > >> > around as an argument, check out web cells > >> > (http://docs.racket-lang.org/web-server/stateless.html?q= > web-server%2Flang%2Fwe#%28mod-path._web-server%2Flang%2Fweb-cells%29) > >> > or web parameters > >> > (http://docs.racket-lang.org/web-server/stateless.html?q= > web-server%2Flang%2Fwe#%28mod-path._web-server%2Flang%2Fweb-param%29). > >> > > >> > > >> > > >> > -Philip > >> > > >> > > >> > > >> > On Tue, Mar 14, 2017 at 1:48 PM, Marc Kaufmann > >> > wrote: > >> > > >> > > >> > > >> > Thanks for the detailed answer Philip! Some of it is definitely over > my > >> > head. The reason I don't pass around the id is that I use the html > field > >> > exactly to track the id and wanted to avoid having to pass around the > >> > argument left and right - an
Re: [racket-users] How to build new formlets that allow passing default values (such as hidden)?
On Wed, Aug 23, 2017 at 8:26 AM, Marc Kaufmann wrote: > Hi again, > > I am now trying to deal with formlets in a more principled fashion and thus > trying to implement, as Philip suggested, to use `send/formlet` and > `embed-formlet`. After a lot of tinkering, I still haven't figured out how > to actually process the formlet (without having to pass it around) with > embed-formlet. Here is the current example: > > (define (debrief request) > (define test-formlet > (formlet > (div "Name:" ,{input-string . => . name}) > (list name))) > (define (response-generator embed/url) > (html-wrapper > `((h1 "Testing Formlets") > (form ([action ,(embed/url testing)] >[method "POST"]) > (p "Here is the displayed formlet") > ;,@(formlet-display test-formlet) ;; THIS WORKS > ,(embed-formlet embed/url test-formlet) > (input ([type "submit"])) > > > The above works without `embed-formlet` with the following definition of > `testing`: > > (define (testing request) > (define result (formlet-process test-formlet request)) > (html-wrapper > `((h1 "Result") > (div > ,(first result) > (send/suspend/dispatch response-generator)) > > But it does not work (or I can't figure out how it works) with > embed-formlet. How do I process the formlet, with the requirement that I do > not want to refer explicitly to `test-formlet`? That is not possible. A formlet defines two things: the rendering and the processing, so it doesn't make sense to process without the processing definition. > Or is this not possible - in > which case, what does `embed-formlet` do that `formlet-processing` doesn't? > Any working example with embed-formlet is appreciate, even if it is not the > same as mine. When you use embed-formlet, the formlet is displayed and when you submit, then the formlet's processing runs and returns to the call-site of send/suspend/dispatch. So you don't separate them. embed-formlet is really simple: (define (embed-formlet embed/url f) `(form ([action ,(embed/url (lambda (r) (formlet-process f r)))]) ,@(formlet-display f))) > Thanks, > Marc > > > On Thu, Mar 16, 2017 at 2:11 PM, Marc Kaufmann > wrote: >> >> Thanks Philip. I checked out the links, but I fear that it's over my head, >> and that I would almost surely screw it up. For now I'll keep passing the >> parameters. >> >> Cheers, >> Marc >> >> On Tuesday, March 14, 2017 at 3:22:39 PM UTC-4, Philip McGrath wrote: >> > If you want it to be part of the continuation without having to pass it >> > around as an argument, check out web cells >> > (http://docs.racket-lang.org/web-server/stateless.html?q=web-server%2Flang%2Fwe#%28mod-path._web-server%2Flang%2Fweb-cells%29) >> > or web parameters >> > (http://docs.racket-lang.org/web-server/stateless.html?q=web-server%2Flang%2Fwe#%28mod-path._web-server%2Flang%2Fweb-param%29). >> > >> > >> > >> > -Philip >> > >> > >> > >> > On Tue, Mar 14, 2017 at 1:48 PM, Marc Kaufmann >> > wrote: >> > >> > >> > >> > Thanks for the detailed answer Philip! Some of it is definitely over my >> > head. The reason I don't pass around the id is that I use the html field >> > exactly to track the id and wanted to avoid having to pass around the >> > argument left and right - and the only ways to pass it on are via forms or >> > by sticking it into the requested URL or by using continuations. I will >> > give >> > the continuation-style solution a shot though, it's probably cleaner to >> > pass >> > the id around as an argument. >> > >> > Cheers, >> > Marc >> > >> > >> > >> > >> > >> > On Tue, Mar 14, 2017 at 1:34 PM, Philip McGrath >> > wrote: >> > >> > In this case it will work despite being a hack, because you know that >> > your id argument affects only the display stage, not the processing stage: >> > however, you can't know in general that this will work for dynamically >> > generated formlets, and personally I would therefore be reluctant to rely >> > on >> > this, both because it is fragile in terms of changes to your implementation >> > of matrix-formlet that you might make later. >> > >> > >> > If you are using native continuations (i.e. not the stateless #lang >> > web-server), you can use send/formlet or embed-formlet to deal with this >> > correctly and easily. (At a lower level, you could also do something >> > like(define-values (xexpr-forest bindings->result i) >> > ((matrix-formlet "3") 0)) >> > to access the low-level rendering, processing function, and next >> > allowable input integer directly.) >> > >> > >> > It is a little more tricky in #lang web-server, because your formlet and >> > it's generated processing function are plain functions, and thus not >> > serializable (see this old thread for discussion: >> > https://groups.google.com/d/topic/racket-users/lMYWjodgpmo/discussion). The >> > easy work-around is to
Re: [racket-users] How to build new formlets that allow passing default values (such as hidden)?
Hi again, I am now trying to deal with formlets in a more principled fashion and thus trying to implement, as Philip suggested, to use `send/formlet` and `embed-formlet`. After a lot of tinkering, I still haven't figured out how to actually process the formlet (without having to pass it around) with embed-formlet. Here is the current example: (define (debrief request) (define test-formlet (formlet (div "Name:" ,{input-string . => . name}) (list name))) (define (response-generator embed/url) (html-wrapper `((h1 "Testing Formlets") (form ([action ,(embed/url testing)] [method "POST"]) (p "Here is the displayed formlet") ;,@(formlet-display test-formlet) ;; THIS WORKS ,(embed-formlet embed/url test-formlet) (input ([type "submit"])) The above works without `embed-formlet` with the following definition of `testing`: (define (testing request) (define result (formlet-process test-formlet request)) (html-wrapper `((h1 "Result") (div ,(first result) (send/suspend/dispatch response-generator)) But it does not work (or I can't figure out how it works) with embed-formlet. How do I process the formlet, with the requirement that I do not want to refer explicitly to `test-formlet`? Or is this not possible - in which case, what does `embed-formlet` do that `formlet-processing` doesn't? Any working example with embed-formlet is appreciate, even if it is not the same as mine. Thanks, Marc On Thu, Mar 16, 2017 at 2:11 PM, Marc Kaufmann wrote: > Thanks Philip. I checked out the links, but I fear that it's over my head, > and that I would almost surely screw it up. For now I'll keep passing the > parameters. > > Cheers, > Marc > > On Tuesday, March 14, 2017 at 3:22:39 PM UTC-4, Philip McGrath wrote: > > If you want it to be part of the continuation without having to pass it > around as an argument, check out web cells (http://docs.racket-lang.org/ > web-server/stateless.html?q=web-server%2Flang%2Fwe#%28mod- > path._web-server%2Flang%2Fweb-cells%29) or web parameters ( > http://docs.racket-lang.org/web-server/stateless.html?q= > web-server%2Flang%2Fwe#%28mod-path._web-server%2Flang%2Fweb-param%29). > > > > > > > > -Philip > > > > > > > > On Tue, Mar 14, 2017 at 1:48 PM, Marc Kaufmann > wrote: > > > > > > > > Thanks for the detailed answer Philip! Some of it is definitely over my > head. The reason I don't pass around the id is that I use the html field > exactly to track the id and wanted to avoid having to pass around the > argument left and right - and the only ways to pass it on are via forms or > by sticking it into the requested URL or by using continuations. I will > give the continuation-style solution a shot though, it's probably cleaner > to pass the id around as an argument. > > > > Cheers, > > Marc > > > > > > > > > > > > On Tue, Mar 14, 2017 at 1:34 PM, Philip McGrath < > phi...@philipmcgrath.com> wrote: > > > > In this case it will work despite being a hack, because you know that > your id argument affects only the display stage, not the processing stage: > however, you can't know in general that this will work for dynamically > generated formlets, and personally I would therefore be reluctant to rely > on this, both because it is fragile in terms of changes to your > implementation of matrix-formlet that you might make later. > > > > > > If you are using native continuations (i.e. not the stateless #lang > web-server), you can use send/formlet or embed-formlet to deal with this > correctly and easily. (At a lower level, you could also do something > like(define-values (xexpr-forest bindings->result i) > > ((matrix-formlet "3") 0)) > > to access the low-level rendering, processing function, and next > allowable input integer directly.) > > > > > > It is a little more tricky in #lang web-server, because your formlet and > it's generated processing function are plain functions, and thus not > serializable (see this old thread for discussion: https://groups. > google.com/d/topic/racket-users/lMYWjodgpmo/discussion). The easy > work-around is to keep the arguments you need to reproduce your formlet > around as part of the closure, e.g. by rewriting your matrix-submission > like this:(define (matrix-submission req id) > > (define-values (number-of-ones user-id) > > (formlet-process (matrix-formlet id) req)) > > ...) > > The alternative is to either recompile the formlet library using #lang > web-server/base or to implement your formlet at a low level using > serial-lambda and not use any of the library tools. > > > > > > In this specific case, though, if you are using this hidden input field > just to remember the user id from one request to the next (i.e. you > wouldn't ever change it on the client side with JavaScript or something), > the best solution is not to put it in the form at all, but have it be part > of the continuation
Re: [racket-users] How to build new formlets that allow passing default values (such as hidden)?
Thanks Philip. I checked out the links, but I fear that it's over my head, and that I would almost surely screw it up. For now I'll keep passing the parameters. Cheers, Marc On Tuesday, March 14, 2017 at 3:22:39 PM UTC-4, Philip McGrath wrote: > If you want it to be part of the continuation without having to pass it > around as an argument, check out web cells > (http://docs.racket-lang.org/web-server/stateless.html?q=web-server%2Flang%2Fwe#%28mod-path._web-server%2Flang%2Fweb-cells%29) > or web parameters > (http://docs.racket-lang.org/web-server/stateless.html?q=web-server%2Flang%2Fwe#%28mod-path._web-server%2Flang%2Fweb-param%29). > > > > -Philip > > > > On Tue, Mar 14, 2017 at 1:48 PM, Marc Kaufmann wrote: > > > > Thanks for the detailed answer Philip! Some of it is definitely over my head. > The reason I don't pass around the id is that I use the html field exactly to > track the id and wanted to avoid having to pass around the argument left and > right - and the only ways to pass it on are via forms or by sticking it into > the requested URL or by using continuations. I will give the > continuation-style solution a shot though, it's probably cleaner to pass the > id around as an argument. > > Cheers, > Marc > > > > > > On Tue, Mar 14, 2017 at 1:34 PM, Philip McGrath > wrote: > > In this case it will work despite being a hack, because you know that your id > argument affects only the display stage, not the processing stage: however, > you can't know in general that this will work for dynamically generated > formlets, and personally I would therefore be reluctant to rely on this, both > because it is fragile in terms of changes to your implementation of > matrix-formlet that you might make later. > > > If you are using native continuations (i.e. not the stateless #lang > web-server), you can use send/formlet or embed-formlet to deal with this > correctly and easily. (At a lower level, you could also do something > like(define-values (xexpr-forest bindings->result i) > ((matrix-formlet "3") 0)) > to access the low-level rendering, processing function, and next allowable > input integer directly.) > > > It is a little more tricky in #lang web-server, because your formlet and it's > generated processing function are plain functions, and thus not serializable > (see this old thread for discussion: > https://groups.google.com/d/topic/racket-users/lMYWjodgpmo/discussion). The > easy work-around is to keep the arguments you need to reproduce your formlet > around as part of the closure, e.g. by rewriting your matrix-submission like > this:(define (matrix-submission req id) > (define-values (number-of-ones user-id) > (formlet-process (matrix-formlet id) req)) > ...) > The alternative is to either recompile the formlet library using #lang > web-server/base or to implement your formlet at a low level using > serial-lambda and not use any of the library tools. > > > In this specific case, though, if you are using this hidden input field just > to remember the user id from one request to the next (i.e. you wouldn't ever > change it on the client side with JavaScript or something), the best solution > is not to put it in the form at all, but have it be part of the continuation. > This could also have security advantages, if you cryptographically sign your > continuations or store them on the server. If that works for your use case, > you could simply write: > (define matrix-formlet > > input-string) > display it with > (matrix-submission > (send/suspend > (λ (k-url) > (response/xexpr > `(html (body (form > ((action "/the-matrix-submitted") > (method "post")) > ,@(formlet-display matrix-formlet) > (input ([type "submit"] > user-id) > and then define matrix-submission as(define (matrix-submission req user-id) > (define number-of-ones > (formlet-process matrix-formlet req)) > ...) > > > > -Philip > > > > > > On Tue, Mar 14, 2017 at 12:01 PM, Marc Kaufmann wrote: > > > Hi, > > > > I have created a formlet like so: > > > > (define (matrix-formlet id) > > (formlet > > (#%# ,{input-string . => . ones} > > ,{(to-string (required (hidden id))) . => . user-id} > > ) > > (values ones user-id))) > > > > I display this as follows: > > > > `(form > > ((action "/the-matrix-submitted") > > (method "post")) > > ,@(formlet-display (matrix-formlet user-id)) > > (input ([type "submit"] > > > > and process it like this: > > > > (define (matrix-submission req) > > (define-values (number-of-ones user-id) > > (formlet-process (matrix-formlet "3") req)) > > ...) > > > > While this works, the formlet I use to display and process are not really the > same, since they are created on the spot, and created with different > parameters. So
Re: [racket-users] How to build new formlets that allow passing default values (such as hidden)?
If you want it to be part of the continuation without having to pass it around as an argument, check out web cells ( http://docs.racket-lang.org/web-server/stateless.html?q=web-server%2Flang%2Fwe#%28mod-path._web-server%2Flang%2Fweb-cells%29) or web parameters ( http://docs.racket-lang.org/web-server/stateless.html?q=web-server%2Flang%2Fwe#%28mod-path._web-server%2Flang%2Fweb-param%29 ). -Philip On Tue, Mar 14, 2017 at 1:48 PM, Marc Kaufmann wrote: > Thanks for the detailed answer Philip! Some of it is definitely over my > head. The reason I don't pass around the id is that I use the html field > exactly to track the id and wanted to avoid having to pass around the > argument left and right - and the only ways to pass it on are via forms or > by sticking it into the requested URL or by using continuations. I will > give the continuation-style solution a shot though, it's probably cleaner > to pass the id around as an argument. > > Cheers, > Marc > > On Tue, Mar 14, 2017 at 1:34 PM, Philip McGrath > wrote: > >> In this case it will work despite being a hack, because you know that >> your id argument affects only the display stage, not the processing stage: >> however, you can't know in general that this will work for dynamically >> generated formlets, and personally I would therefore be reluctant to rely >> on this, both because it is fragile in terms of changes to your >> implementation of matrix-formlet that you might make later. >> >> If you are using native continuations (i.e. not the stateless #lang >> web-server), you can use send/formlet or embed-formlet to deal with this >> correctly and easily. (At a lower level, you could also do something like >> >>> (define-values (xexpr-forest bindings->result i) >>> ((matrix-formlet "3") 0)) >> >> to access the low-level rendering, processing function, and next >> allowable input integer directly.) >> >> It is a little more tricky in #lang web-server, because your formlet and >> it's generated processing function are plain functions, and thus not >> serializable (see this old thread for discussion: https://groups.goo >> gle.com/d/topic/racket-users/lMYWjodgpmo/discussion). The easy >> work-around is to keep the arguments you need to reproduce your formlet >> around as part of the closure, e.g. by rewriting your matrix-submission >> like this: >> >>> (define (matrix-submission req id) >>> (define-values (number-of-ones user-id) >>> (formlet-process (matrix-formlet id) req)) >>> ...) >> >> The alternative is to either recompile the formlet library using #lang >> web-server/base or to implement your formlet at a low level using >> serial-lambda and not use any of the library tools. >> >> In this specific case, though, if you are using this hidden input field >> just to remember the user id from one request to the next (i.e. you >> wouldn't ever change it on the client side with JavaScript or something), >> the best solution is not to put it in the form at all, but have it be part >> of the continuation. This could also have security advantages, if you >> cryptographically sign your continuations or store them on the server. If >> that works for your use case, you could simply write: >> (define matrix-formlet >> input-string) >> display it with >> >>> (matrix-submission >>> (send/suspend >>> (λ (k-url) >>> (response/xexpr >>> `(html (body (form >>>((action "/the-matrix-submitted") >>> (method "post")) >>>,@(formlet-display matrix-formlet) >>>(input ([type "submit"] >>> user-id) >> >> and then define matrix-submission as >> >>> (define (matrix-submission req user-id) >>> (define number-of-ones >>> (formlet-process matrix-formlet req)) >>> ...) >> >> >> -Philip >> >> On Tue, Mar 14, 2017 at 12:01 PM, Marc Kaufmann < >> marc.kaufman...@gmail.com> wrote: >> >>> Hi, >>> >>> I have created a formlet like so: >>> >>> (define (matrix-formlet id) >>> (formlet >>> (#%# ,{input-string . => . ones} >>> ,{(to-string (required (hidden id))) . => . user-id} >>> ) >>> (values ones user-id))) >>> >>> I display this as follows: >>> >>> `(form >>> ((action "/the-matrix-submitted") >>>(method "post")) >>> ,@(formlet-display (matrix-formlet user-id)) >>> (input ([type "submit"] >>> >>> and process it like this: >>> >>> (define (matrix-submission req) >>> (define-values (number-of-ones user-id) >>> (formlet-process (matrix-formlet "3") req)) >>> ...) >>> >>> While this works, the formlet I use to display and process are not >>> really the same, since they are created on the spot, and created with >>> different parameters. So far it seems to work, but I am worried that this >>> will break down, and clearly this isn't the right way to go about creating >>> parametrizable formlets. >>> >>> The questions are (i) is the above going to work despite being a hack, >>> and (ii) is there
Re: [racket-users] How to build new formlets that allow passing default values (such as hidden)?
Thanks for the detailed answer Philip! Some of it is definitely over my head. The reason I don't pass around the id is that I use the html field exactly to track the id and wanted to avoid having to pass around the argument left and right - and the only ways to pass it on are via forms or by sticking it into the requested URL or by using continuations. I will give the continuation-style solution a shot though, it's probably cleaner to pass the id around as an argument. Cheers, Marc On Tue, Mar 14, 2017 at 1:34 PM, Philip McGrath wrote: > In this case it will work despite being a hack, because you know that your > id argument affects only the display stage, not the processing stage: > however, you can't know in general that this will work for dynamically > generated formlets, and personally I would therefore be reluctant to rely > on this, both because it is fragile in terms of changes to your > implementation of matrix-formlet that you might make later. > > If you are using native continuations (i.e. not the stateless #lang > web-server), you can use send/formlet or embed-formlet to deal with this > correctly and easily. (At a lower level, you could also do something like > >> (define-values (xexpr-forest bindings->result i) >> ((matrix-formlet "3") 0)) > > to access the low-level rendering, processing function, and next allowable > input integer directly.) > > It is a little more tricky in #lang web-server, because your formlet and > it's generated processing function are plain functions, and thus not > serializable (see this old thread for discussion: https://groups. > google.com/d/topic/racket-users/lMYWjodgpmo/discussion). The easy > work-around is to keep the arguments you need to reproduce your formlet > around as part of the closure, e.g. by rewriting your matrix-submission > like this: > >> (define (matrix-submission req id) >> (define-values (number-of-ones user-id) >> (formlet-process (matrix-formlet id) req)) >> ...) > > The alternative is to either recompile the formlet library using #lang > web-server/base or to implement your formlet at a low level using > serial-lambda and not use any of the library tools. > > In this specific case, though, if you are using this hidden input field > just to remember the user id from one request to the next (i.e. you > wouldn't ever change it on the client side with JavaScript or something), > the best solution is not to put it in the form at all, but have it be part > of the continuation. This could also have security advantages, if you > cryptographically sign your continuations or store them on the server. If > that works for your use case, you could simply write: > (define matrix-formlet > input-string) > display it with > >> (matrix-submission >> (send/suspend >> (λ (k-url) >> (response/xexpr >> `(html (body (form >>((action "/the-matrix-submitted") >> (method "post")) >>,@(formlet-display matrix-formlet) >>(input ([type "submit"] >> user-id) > > and then define matrix-submission as > >> (define (matrix-submission req user-id) >> (define number-of-ones >> (formlet-process matrix-formlet req)) >> ...) > > > -Philip > > On Tue, Mar 14, 2017 at 12:01 PM, Marc Kaufmann > wrote: > >> Hi, >> >> I have created a formlet like so: >> >> (define (matrix-formlet id) >> (formlet >> (#%# ,{input-string . => . ones} >> ,{(to-string (required (hidden id))) . => . user-id} >> ) >> (values ones user-id))) >> >> I display this as follows: >> >> `(form >> ((action "/the-matrix-submitted") >>(method "post")) >> ,@(formlet-display (matrix-formlet user-id)) >> (input ([type "submit"] >> >> and process it like this: >> >> (define (matrix-submission req) >> (define-values (number-of-ones user-id) >> (formlet-process (matrix-formlet "3") req)) >> ...) >> >> While this works, the formlet I use to display and process are not really >> the same, since they are created on the spot, and created with different >> parameters. So far it seems to work, but I am worried that this will break >> down, and clearly this isn't the right way to go about creating >> parametrizable formlets. >> >> The questions are (i) is the above going to work despite being a hack, >> and (ii) is there a correct and easy way to do the same thing? >> >> Cheers, >> Marc >> >> -- >> You received this message because you are subscribed to the Google Groups >> "Racket Users" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to racket-users+unsubscr...@googlegroups.com. >> For more options, visit https://groups.google.com/d/optout. >> > > -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For
Re: [racket-users] How to build new formlets that allow passing default values (such as hidden)?
In this case it will work despite being a hack, because you know that your id argument affects only the display stage, not the processing stage: however, you can't know in general that this will work for dynamically generated formlets, and personally I would therefore be reluctant to rely on this, both because it is fragile in terms of changes to your implementation of matrix-formlet that you might make later. If you are using native continuations (i.e. not the stateless #lang web-server), you can use send/formlet or embed-formlet to deal with this correctly and easily. (At a lower level, you could also do something like > (define-values (xexpr-forest bindings->result i) > ((matrix-formlet "3") 0)) to access the low-level rendering, processing function, and next allowable input integer directly.) It is a little more tricky in #lang web-server, because your formlet and it's generated processing function are plain functions, and thus not serializable (see this old thread for discussion: https://groups.google.com/d/topic/racket-users/lMYWjodgpmo/discussion). The easy work-around is to keep the arguments you need to reproduce your formlet around as part of the closure, e.g. by rewriting your matrix-submission like this: > (define (matrix-submission req id) > (define-values (number-of-ones user-id) > (formlet-process (matrix-formlet id) req)) > ...) The alternative is to either recompile the formlet library using #lang web-server/base or to implement your formlet at a low level using serial-lambda and not use any of the library tools. In this specific case, though, if you are using this hidden input field just to remember the user id from one request to the next (i.e. you wouldn't ever change it on the client side with JavaScript or something), the best solution is not to put it in the form at all, but have it be part of the continuation. This could also have security advantages, if you cryptographically sign your continuations or store them on the server. If that works for your use case, you could simply write: (define matrix-formlet input-string) display it with > (matrix-submission > (send/suspend > (λ (k-url) > (response/xexpr > `(html (body (form >((action "/the-matrix-submitted") > (method "post")) >,@(formlet-display matrix-formlet) >(input ([type "submit"] > user-id) and then define matrix-submission as > (define (matrix-submission req user-id) > (define number-of-ones > (formlet-process matrix-formlet req)) > ...) -Philip On Tue, Mar 14, 2017 at 12:01 PM, Marc Kaufmann wrote: > Hi, > > I have created a formlet like so: > > (define (matrix-formlet id) > (formlet > (#%# ,{input-string . => . ones} > ,{(to-string (required (hidden id))) . => . user-id} > ) > (values ones user-id))) > > I display this as follows: > > `(form > ((action "/the-matrix-submitted") >(method "post")) > ,@(formlet-display (matrix-formlet user-id)) > (input ([type "submit"] > > and process it like this: > > (define (matrix-submission req) > (define-values (number-of-ones user-id) > (formlet-process (matrix-formlet "3") req)) > ...) > > While this works, the formlet I use to display and process are not really > the same, since they are created on the spot, and created with different > parameters. So far it seems to work, but I am worried that this will break > down, and clearly this isn't the right way to go about creating > parametrizable formlets. > > The questions are (i) is the above going to work despite being a hack, and > (ii) is there a correct and easy way to do the same thing? > > Cheers, > Marc > > -- > You received this message because you are subscribed to the Google Groups > "Racket Users" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to racket-users+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. > -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
[racket-users] How to build new formlets that allow passing default values (such as hidden)?
Hi, I have created a formlet like so: (define (matrix-formlet id) (formlet (#%# ,{input-string . => . ones} ,{(to-string (required (hidden id))) . => . user-id} ) (values ones user-id))) I display this as follows: `(form ((action "/the-matrix-submitted") (method "post")) ,@(formlet-display (matrix-formlet user-id)) (input ([type "submit"] and process it like this: (define (matrix-submission req) (define-values (number-of-ones user-id) (formlet-process (matrix-formlet "3") req)) ...) While this works, the formlet I use to display and process are not really the same, since they are created on the spot, and created with different parameters. So far it seems to work, but I am worried that this will break down, and clearly this isn't the right way to go about creating parametrizable formlets. The questions are (i) is the above going to work despite being a hack, and (ii) is there a correct and easy way to do the same thing? Cheers, Marc -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.