Pylons 1 includes a minimum form pattern based FormEncode, WebHelpers,
and @validate. Pyramid does not have any form dependencies; it's up to
you to choose a library. A baseline scenario using the closest
equivalent gives us:
Form creation: WebHelpers HTML tags
Validation: FormEncode
Error display: FormEncode htmlfill
Usage: pyramid_simpleform (new package by zeemonkey)
Usage: two-view (one for form, another for submission)
Database records: WebHelpers ModelTags
Internationalization: FormEncode messages property
REST: pyramid_routehelper (not written yet; equivalent to Routes
map.resource)
This does everything except form generation; instead it provides
helpers to create your own form in your template. The question is, is
this still the best usage pattern to promote in 2011, and if so, are
these the best packages to do it? I also need to survey the various
alternative form packages and rank them into beginner/advanced, and
note how widely used and supported they are. So this email is to
collect feedback for that: what are people using, and what do they
think makes sense for Pyramid.
My own feeling is to stick with this pattern as the first
recommendation. It's pyramidesque and flexible. Mako has a
call-with-content feature and a new unobtrusive syntax that allows
template functions to look almost like built-in template commands; we
have never sufficiently explored this as a basis for a form library. I
also like how FormEncode's validators can be used generally for
validation and conversion: I use them to check and transform the INI
settings at startup. I also use formencode.declarative as a general
base class because it handles constructor args for you.
However, FormEncode is 6+ years old, its documentation is somewhat
confusing for using it in a Pylons/Pyramid context, some things are
undocumented, and the source has some code that looks like dead ends
(backward compatibility only). I've been meaning to write a new
FormEncode manual for years but have never had time to. So maybe it's
time to streamline it into a new package.
Which brings us to Formish and Deform. At first glance, Formish seems
to be a streamlining of FormEncode into discrete classes for schemas,
validation, type conversion (which it separates from validation), with
specific support for nested form data and file uploads. It also adds a
layer for form generation using Mako. Deform, by our own ChrisM, is a
reimplementation of the Formish concept using different libraries and
Chameleon templates.
So, for those who've used them, is this true? Are they equivalent to
FormEncode, or are they missing any of FormEncode's functionality? How
well does it work separating validation from type conversion? To me it
seems like you have to type convert in order to validate, and a failed
conversion is a failed validation, so I don't really see the point in
separating them, and I'm concerned the schema definitions may be more
verbose than FormEncode's is. Has there been any work on Mako
templates for Deform? What has users' experience with these libraries
been?
There's also WTForms, which we considered recently for Pylons 2. It
has a simple interface like Django newforms which we liked, but it
wasn't as flexible as FormEncode and the validators seemed like they
weren't designed for non-web use, so we were afraid of losing some
existing functionality. Is anyone using WTForms with Pylons or Pyramid
who would like to comment?
ToscaWidgets has always been popular but has been reputed as harder to
learn and bigger, so it seems to belong to the "advanced forms"
category.
Then there are several form/model generators tied to SQLAlchemy, such
as FormAlchemy, GeoFormAlchemy, Sprox (which seems to have replaced
DBSprockets?), etc. I'm not sure of the differences between these.
Those tied to SQLAlchemy are subset of form generation, so they would
go in a subsection.
Another issue is one-view vs two-view form processing. The tradtional
way (before I came to Pylons) was to use one view with an 'if' that
would display the form if there are no POST variables, or validate it
if there are, and an inner 'if' to do the action if the validation
succeeds, or to redisplay the form with errors if it fails. Pylons
@validate went with a two-form approach, which means you have to call
the form view from the submission view if the validation fails. And
REST essentially requires a two-vlew approach because the form and
submission are on different URLs, and the same URL is doubled up for
submitting one form (PUT or POST) and displaying a different page
(GET). So different URLs for form and submission require two views.
Most people have kept the two-view approach with @validate even for
non-REST forms. I think it would be best to support both approaches,
two-view and one-view.
One thing I was concerned about in pyramid_simpleform
(http://packages.python.org/pyramid_simpleform/) is that the view
handler has the form view and submission view that look almost the
same. It's like one could go to either URL? What's the purpose of
this, and how does it handle the case of failed validation?
Anyway, if you have any ideas on what should be in the Pyramid-Pylons
form howto (which will probably be the Pyramid form howto too, since
there isn't one of those I could find), now's the time to speak up.
--
Mike Orr <slugg...@gmail.com>
I don't really have something to say because I'm using FormAlchemy for
years now and it work fine with pyramid (and all webob based
application) too so I will continue to use it.
So I'm really not objective. I just want to end up the misunderstanding.
On Mon, Jan 17, 2011 at 8:23 PM, Mike Orr <slugg...@gmail.com> wrote:
(...)
>
> Then there are several form/model generators tied to SQLAlchemy, such
> as FormAlchemy, GeoFormAlchemy, Sprox (which seems to have replaced
> DBSprockets?), etc. I'm not sure of the differences between these.
> Those tied to SQLAlchemy are subset of form generation, so they would
> go in a subsection.
>
That's not true. FormAlchemy does not rely on SQLAlchemy although it
is a required dependency.
I've wrote some subclass of FormAlchemy's Field and FieldSet to
implement other backends.
As an example there is an implementation for zope.schema:
from formalchemy.ext.zope import FieldSet
from zope.interface import Interface, implements
from zope import schema
class IObj(Interface):
id = schema.TextLine()
class Obj(object):
implements(IObj)
fs = FieldSet(IObj)
obj = Obj()
fs.rebind(obj, data={'Obj--id': 'my id'})
if fs.validate():
fs.sync()
assert obj.id == 'my id'
print fs.render()
This will output:
<div>
<label class="field_req" for="Obj--id">id</label>
<input id="Obj--id" name="Obj--id" type="text" value="my id" />
</div>
<script type="text/javascript">
//<![CDATA[
document.getElementById("Obj--id").focus();
//]]>
</script>
You can read more about this in the documentation:
http://docs.formalchemy.org/formalchemy/ext/zope.html
There is also a ldap implementation not listed in the documentation:
http://pypi.python.org/pypi/afpy.ldap
But... this is totally out of topic. Sorry for the noise.
Regards,
--
Gael
TQ.
--
Regards,
-Sharil I. Shafie-