Saturday, July 18, 2009

why HTML::FormHandler...

Dan Dascalescu (dandv) said about FormHandler that it "would be awesome if the POD could mention what's different from FormFu, why create the module at all." I have tried to put some of that into the pod, but apparently it's not enough. So I've been thinking about this issue (the problem of too many packages and not enough info on the differences), and I think that there's are a number of things getting in the way of being clear enough and loud enough with "what's different".

For one thing, Carl Franks and many other people have put lots of work and time into FormFu and like it. The reasons that HTML::FormHandler exists are personal, very human feelings and reactions that don't belong in "official documentation". In order for the statements about what I think to not be offensive, they have to be put into the form of: "This is the way I feel, this is the way I reacted. YMMV." I don't want to start a flame war and I don't want to hurt anybody's feeling. (Yeah, I know that's kinda girly. So sue me.)

The next problem is that I don't really know FormFu. When I was looking for a form package a year and a half ago I looked at it and I just could not bring myself to use it. I hated it on sight. So I'm not competent to compare FormHandler and FormFu. (Anybody willing to submit a doc patch who has used FormFu?)

The last problem is that I don't think that I'm necessarily the right person to be really loud and clear about the advantages of FormHandler. I'm too close to it. It would feel like I'm tooting my own horn, boasting. I'm almost certainly not going to be seeing its weaknesses clearly. I think that somebody else will have to make the definitive comparison.

I guess I can talk about why FormHandler exists, but many of the reasons are human reasons, not technical reasons.

Programmers have emotions, sometimes strong emotions, about the tools and libraries that they use. Some packages are clean, easy, fun. Modifications can be made easily. The pieces can be clumped together in ways that are accessible and readable. Programmers can have strong emotions about variable names. So clearly they're a little unbalanced. (You should have seen the arguments that me and my manager had about whether a database column should be named 'report_no' or 'report_num'. It was downright silly but we both had emotions that were too strong to give up our positions. About a database column name.) Sometimes the emotions are irrational, or intuitions based on experience that can't easily be put into words.

So I'm trying to remember why I looked at FormFu and thought: "Yuck. I'm not going to use that. No, no, no." (Warning: this may not be helpful to you in making a choice of packages.)

The first problem that I had with FormFu was the yaml config files. I hate YAML. With a passion. I think that whitespace sensitive formats are stupid. I hated hated hated the tab-sensitivity of make files, and YAML was just more of the same. My eyes/brain can't adjust to pulling out the significant information when I glance over a YAML file. Yes, I KNOW that FormFu can use any kind of Config::General format. But all of the documentation was in YAML and I Didn't Want to Look at It.

There. I told you this wasn't going to be a rational technical discussion, didn't I?

I also hated the fact that the forms were even defined in config files to start with. I looked at it, and my first thought was: but what if I want to do something in a way that hasn't been pre-defined? Yes, I know you can make your own constraint classes, yadda, yadda, yadda. It was too disconnected to the particular form. I looked at the way it worked and I got claustrophobia. I felt like I would be having to adapt myself to FormFu, instead of me being able to adapt FormFu to the way I wanted to work. FormFu code couldn't be easily subclassed or overridden for a particular form. You'd have to do something weird to change the way that it worked. I have no idea if my reaction was accurate or not. I couldn't bring myself to try it enough to find out.

It felt heavyweight, cumbersome, and rigid. And no, I can't give you detailed list of why it felt that way to me. I read the documentation and listened to people complain in #catalyst, and that was it.

Speaking of #catalyst, that was a big source of my dislike for FormFu. Lots of people showed up trying to do something particular with HTML and could not figure out how to do it. I saw people spend days on HTML changes that would have taken them minutes by hand. I saw how hard it was to figure out how to achieve particular results (that I can't remember anymore). This may be totally unfair of me. Maybe boatloads of people will eventually show up complaining about FormHandler in the same way. But I'm trying to be honest here (painfully so, maybe). And those complaints did play a part in my disinclination to use a package that was so hard to customize.

So I looked at the other options out there. Formbuilder was deprecated. Rose Forms was ok, but not quite right. Reaction was interesting but overkill for my application. I found Form::Processor, and it certainly wasn't perfect, but at least the thought of using it didn't depress me. I liked the architecture and I liked the way that it could automatically save forms to the database. The problem was that it didn't have a DBIC model. I decided to write one.

Unfortunately Form::Processor had almost no tests. It had a few field tests, and a small handful of non-database form tests. There were NO tests for interfacing with the database. There were no examples for interfacing with the database. So the first thing I had to do was create a CDBI example so that I could figure out how a DBIC model would work. Eventually I got the DBIC model to work, and uploaded my first package to CPAN. They did not come and arrest me for inadequate code.

I was happy enough with Form::Processor for quite a while. Then I started to use Moose in most of my new code. Form::Processor used Rose::Object. I really liked Moose and it seemed silly to be using two different object systems. The Form::Processor code, because it used Rose::Object, looked easy to convert to Moose. So in a burst of energetic yak shaving, I converted it to Moose.

Bill Moseley, the owner of Form::Processor, had some interest in moving toward Moose, but he didn't have time to work on it. There was no public repository. He had a suite of tests he wanted it to pass that I didn't have access to. There were many Moose features that couldn't be used and feature improvements that couldn't be done because they wouldn't be compatible with Bill's codebase.

I was getting some interest in a Moosified form processor from other programmers and I liked how my new code was shaping up. So I put the code up on github and released it to CPAN. Followed by deafening silence. But I had been communicating with Zbigniew Lukasiak about the new project and he had lots of experience with FormFu and ideas he wanted to try out, so he joined the project, which was a godsend. It's so much better to have other progammers contributing too.

So now it's six months from the first CPAN release. I've gotten a lot of positive feedback from people who've used it who like it. The codebase feels more stable now and we've implemented most of the large features we had in mind (though we're hoping for better rendering in the future...)

We've tried hard to make the API consistent, we've refactored to support compound and repeatable fields. We have a comprehensive test suite. It still seems to be very easy to customize - Moose helps with that. To me, it feels flexible, not cumbersome and rigid. You can use hand-built HTML if you want. The rendering is straightforward and simple to a fault. Adding new features has not been painful. I'm happy with it. YMMV.

I suspect that this was NOT what Dan had in mind with his request for 'why create the module at all'. It might be of more interest to a sociologist studying open source than somebody looking for reasons to pick a package. But it is the answer that I have, such as it is.


Bob said...

I have to agree. I've used CGI::Formbuilder with great success.

If there's an issue you can just go into the source and fix it. Yea Nate's not working on it anymore and he's turned on the perl community - but it's still a great package.

I've been wanting to bail on formbuilder for a while since it appears to be abandonware. but FormFu doesn't look like where I want to go unless the interface gets way more robust on the code site.

zby said...

One reason that at my blog I started to post about API design (or for that matter also the post about scaffoldings and other more theoretical posts) was to give us some more objective ways to discuss those matters. But it is still very hard.

matt said...

The flexibility is the best part, I can have a single call to a high-level template that enumerates the form fields, loads widget templates and generates its own HTML, or I can write all the HTML myself and use HFH just to provide form values. Or something in between.

It's also really nice to be able to rely on Moose for things like form roles, MooseX::Types validation etc. Definitely my preferred form handler!

matt said...

I quickly embraced FormFu but am now moving into HFH because it offers potentially clean separation of concerns (data representation, validation, rendering...). FormFu seems decently powerful but everything seems tangled enough to damage extensibility.

abraxxa said...

I've worked a bit on HTML::FormFu::ExtJS and the code is indeed hard to understand and doesn't look clean to me.
When deciding for a form generator I choose FormFu over FormHandler because of the ExtJS 'feature'.
You don't have to use a config file but instead pass the config hash to new or populate.
I auto-generate my ExtJS forms for my DBIC model that way.

Dan Dascalescu said...


Dan Dascalescu here. Thanks for "coming out". This is actually what I expected - an established programmer's style is sometimes really hard to change when it comes to the oddest things:

* Matt Trout has no problem writing POD docs, helping lots of people on #catalyst and blogging, but he won't touch a wiki no matter what (I wanted to link to his account on the Catalyst wiki, but I found that he doesn't have one).

* I saw lots of people wrestling with the command line to do basic file management, but they just won't use a file manager like Midnight Commander, not even after being shown how the same operations can be done a few times faster (and without typos).

* For the life of me, I myself can't get past hating the guts of Java and PHP, even though I started out as a C programmer 12 years ago, and both Java and PHP are OO-languages and have regexps and are more similar than different from Perl.

The point I'm trying to make is that if the style of a piece of software doesn't match yours, it's actually counter-productive to force yourself to use it, and more productive instead to design a similar wheel.

Bryan said...

I had pretty much exactly the same reaction you did when I started trying to use FormFu. I even went as far as to start developing my own system of handling forms on Catalyst < 5.8 (with some similarity to HFH). Now that I have found HFH, I plan to migrate everything over.

abraxxa said...

FYI: I removed the HTML::FormFu::ExtJS dependency from my Catalyst app on Monday.
Now I can use all possibilities of ExtJS without being limited by FormFu::ExtJS (especially using user extensions).
For doing html forms I'll take a look at HFH next time I need one.

Ben said...

Thanks for great tips.
Custom website design

Dave Hodgkinson said...

Three years later and I've just started using HTML::FormHandler having used assorted bodges in the past.

I found the "user registration" example, implemented it quickly, then did my own crud on another table and it was SO easy. Now to get deeper into some other things, and probably learn more DBIC jargon, and also naming stuff for CSS purposes, but it's all looking good so far.

Thanks for a great toolkit!

S├ębastien Nadeau said...

Almost 4 years later, too bad Formbuilder isn't maintained anymore, I just loved it. But thank you for the feedback Dave, it's giving me a good idea where I should go for a replacement.