Parametrized route uri for defform.

1 view
Skip to first unread message

Nicolas Buduroi

unread,
Dec 2, 2010, 2:43:24 AM12/2/10
to Sandbar Library
Hi, I've recently began using sandbar and it is really great! The
first wall I've hit is the lack of support for parametrized uri for
defform. e.g.:

(forms/defform post-form "/group/:group-id/post/edit"
...

I didn't find a way to do this so I read the code a bit and ended up
writing a patch to add this feature:

https://github.com/budu/sandbar/commit/11fff7195606a588dce9e5e68e66250e26cc4fb5

I'm not used enough to the code to say if it's clean and doesn't know
if it affect other parts like ajax forms and extend-form, but it's
backward compatible and doesn't break any tests. Do you think it's a
good idea? Is this implementation good enough?

P.S.: There's a spam post left in this group. Also, if you need help
to moderate it, I'm already a moderator for the Compojure group, I'll
be glad to help.

Brenton

unread,
Dec 2, 2010, 2:11:26 PM12/2/10
to Sandbar Library
Nicolas,

I have pulled your change into sandbar and pushed version 0.4.0-
SNAPSHOT which contains this change.

I have also made you a manager for this group.

I have recently been running into a lot of problems with defform. It
is perfect for when you need a simple form but most of the time I need
to do something special depending on the current request. It is just
not flexible enough. And extend-form is a horrible idea.

I have been thinking about how to do the same thing without using a
macro and I think I have it. I will be doing all of the new form work
in sandbar.dev.forms which I will push to GitHub later today. When I
am done it shouldn't be too much trouble to port code from defform to
the new function as they will have an almost identical contract.
Instead of a macro that generates code it will be a function which
generates a form handler function which can handle both get and post
requests for a form.

For example instead of this:

(defform user-form "/user/edit"
:fields [(hidden :id)
(textfield "Username" :username)]
:load #(db/find-user %)
:on-cancel "/"
:on-success
#(do
(db/store-user %)
(set-flash-value! :user-message "User has been saved.")
"/")
:validator
#(if (< (count (:username %)) 5)
(add-validation-error % :username "Username must have at least 5
chars.")
%))

you would write

(def user-form
(make-form :user-form
:fields [(hidden :id)
(textfield "Username" :username)]
:load #(db/find-user %)
:on-cancel "/"
:on-success
#(do
(db/store-user %)
(set-flash-value! :user-message "User has been saved.")
"/")
:validator
#(if (< (count (:username %)) 5)
(add-validation-error % :username "Username must have at least
5 chars.")
%)))

The main improvements will be:

1) everything about the form will be able to specified as a literal or
a function of the request (even the form fields)
2) it will no longer create routes for you so you will be able to
define you own routes and route parameters
3) drastically less and clearer implementation code
4) functions instead of macros
5) it will be easier to create forms that are embedded within other
content
6) more concise form field definitions

I mention this in case you are struggling with other aspects of
defform. At this point I think that it is not worth fixing and another
approach is warranted. I will be interested to hear your feedback on
the new approach.

Thanks,
Brenton

On Dec 1, 11:43 pm, Nicolas Buduroi <nbudu...@gmail.com> wrote:
> Hi, I've recently began using sandbar and it is really great! The
> first wall I've hit is the lack of support for parametrized uri for
> defform. e.g.:
>
> (forms/defform post-form "/group/:group-id/post/edit"
> ...
>
> I didn't find a way to do this so I read the code a bit and ended up
> writing a patch to add this feature:
>
> https://github.com/budu/sandbar/commit/11fff7195606a588dce9e5e68e6625...

Nicolas Buduroi

unread,
Dec 2, 2010, 3:05:10 PM12/2/10
to Sandbar Library
On Dec 2, 2:11 pm, Brenton <bashw...@gmail.com> wrote:
> I have recently been running into a lot of problems with defform. It
> is perfect for when you need a simple form but most of the time I need
> to do something special depending on the current request. It is just
> not flexible enough. And extend-form is a horrible idea.

I understand your points, for now I just used sandbar for simple
forms, so it's really fantastic. After looking at the code for some
time I realized that flexibility was a weak point.

> I have been thinking about how to do the same thing without using a
> macro and I think I have it. I will be doing all of the new form work
> in sandbar.dev.forms which I will push to GitHub later today. When I
> am done it shouldn't be too much trouble to port code from defform to
> the new function as they will have an almost identical contract.
> Instead of a macro that generates code it will be a function which
> generates a form handler function which can handle both get and post
> requests for a form.

This is a great idea!

> (def user-form
>   (make-form :user-form

You could still provide a defform macro as a shortcut to "(def ...
(make-form".

> The main improvements will be:
>
> 1) everything about the form will be able to specified as a literal or
> a function of the request (even the form fields)

That should really help the flexibility issue.

> 2) it will no longer create routes for you so you will be able to
> define you own routes and route parameters

I was thinking of a way to generate RESTful routes for forms
yesterday. I'll see how it could work with your changes.

> 3) drastically less and clearer implementation code

That should be the best improvement, the gigantic defform macro was a
little bit frightening. ;-)

> 4) functions instead of macros

Always a good idea!

> 5) it will be easier to create forms that are embedded within other
> content
> 6) more concise form field definitions

Lots of good points, sandbar is headed to become an essential library
for Clojure web development.

> I mention this in case you are struggling with other aspects of
> defform. At this point I think that it is not worth fixing and another
> approach is warranted. I will be interested to hear your feedback on
> the new approach.

I'm eager to see these change, but I don't want to put pressure on
you, take your time.

Thanks

Brenton

unread,
Dec 2, 2010, 3:28:32 PM12/2/10
to Sandbar Library
Nicolas,

Good points.

> You could still provide a defform macro as a shortcut to "(def ...
> (make-form".

I will do that.

> I was thinking of a way to generate RESTful routes for forms
> yesterday. I'll see how it could work with your changes.

I would love to hear your ideas.

Thanks. And keep contributing.

Brenton
Reply all
Reply to author
Forward
0 new messages