Ian Bicking: the old part of his blog

Further FormEncode Work...

FormEncode, which has languished for a while, is starting to really come together. Peter Hunt added an enhancement to htmlfill for Subway that allows you to define a validation schema directly in the form, like:

<input type="text" name="username" form:required="yes">
<input type="text" name="email" form:validator="email">

I still have to add something for automatic error insertion (right now you have to put in explicit <form:error name="tag_name"> tags), but with the two of those together I think it will be very easy to casually define forms, and won't even require "programming".

What makes me particularly happy about this is that I don't feel like anything is being compromised. It's really easy to define the same schema outside the form:

class MySchema(schema.Schema):
    username = validators.NotEmpty()
    email = validators.Email()

I think there will be a very smooth curve from the simplest techniques to the most sophisticated -- you don't have to start learning Big New Ideas to use the system in a more sophisticated way, you just have to learn a series of Small New Ideas. And I don't see any ceiling -- this could be reasonably used on the most complex forms or the simplest ones, where the forms are determined either in a completely ad hoc way or entirely programmatically.

I started playing around with the glue that pulls the form handling together; I think I'll have to really use it some to get a better feel for it. But I'm feeling close to a real FormEncode release, and one that is useable, not just for early adopters.

Created 14 Mar '05


I like the way this uses the form to include some basic validation. To me, it seems like the best approach. I agree with your comments in an earlier post where you discussed using completely programmatically generated forms vs styling your own forms.

I used a similar approach as Formencode when collecting values under Mason, using a HTML token parser to parse the form and put errors in (as htmlfill does) that I described on an earlier blog post.

Now that I've switched to myghty though, I've been looking for the equivilant Python version, Formencode with htmlfill and validators looks like it handles it all. While you describe it as an "early adopter" release, I'll give it a spin anyways. Any idea how much the syntax would change before you get to a formal release?

# Ben Bangert

I've been playing with htmlfill and the validators for a few hours, already noticed what I think is a bug. htmlfill has no handler to deal with input type='image'. After adding it to the block that skips 'button' and those types, it works fine again.
# Ben Bangert

I really like how htmlfill works. I think it can function as neat templating system too! If we just learn it about new types of widgets, so it can fill them... Maybe using some kind of schema:

class TableWidget:
    class_ = 'grid' #maybe htmlfill can use css class to find element in the page?
    rows = RepeatWidget()
    paging = PagingWidget() 

IMHO even most fancy designed website can be split into standard widgets... Well, maybe I want it to be so :))

# Ksenia

I'm actually very reluctant to add something like this -- that's the kind of complexity that htmlfill is specifically meant to avoid, because I've gone down that path before and it didn't work well. But the form building you are thinking of could be implemented separately -- this is some of what formgen is meant to provide. You can't quite do this now, but something like this should be possible at some point:

from formgen import *
class CCField(FormTableLayout):
    layout = [['cc_name'], 
              ['cc_number', 'cc_type', 'cc_expiration', '=MM/YY']] 
        # That last item is a literal instruction
    cc_name = Text(size=40)
    cc_number = Text(size=16)
    cc_type = Select(selections=['Visa', 'Mastercard', 'AmEx'])
    cc_expiration = Text(size=5)

And then that would be a reusable "widget". But it just gets rendered to HTML, and htmlfill fills it in -- nothing more. Another subclass of Layout might even work with a template, but create the <input...> tags and whatnot.

# Ian Bicking