[Zope3-dev] Re: [Zope3-Users] z3c.form 1.0.0 released!

Hermann Himmelbauer dusty at qwer.tk
Thu May 31 03:48:05 EDT 2007


Am Donnerstag, 31. Mai 2007 08:09 schrieb Maciej Wisniowski:
> >> It would be very interesting to see RDBMS interaction. Formlib for
> >> example is not trivial to use with RDBMS especially because of a lack
> >> of documentation and because everything seems to be written with ZODB
> >> objects in mind.
> >
> > It works together with a mapper like SQLAlchemy (and z3c.zalchemy).
> >
> > IMHO, it is not formlib's task to do mappings like that.
>
> Not sure what mappings you're talking about. I just want to
> know how can I get some data from somewhere (it may be a
> file, RDBMS or other external source) and display it in a form,
> then edit this data etc. Formlib default forms (EditForm, AddForm)
> assume that it works with content objects and I just want to call
> SQLScript to get data for my form and to commit it back to RDBMS.
> Not so difficult but there are no docs and no demos for this with
> formlib. Thats why  I'd like to know how to do such things
> with z3c.form.

I also still struggle with this issue. In my case, I have the following 
scenarios:

- Some ORM-object attributes directly map to fields, but these attributes may 
be in referenced ORM-objects
- Sometimes I want to map the first referenced ORM-object (which is 
represented as the first list entry) to a field.

However, any field which is displayed is somewhere already described as an 
interface schema field for an ORM object, which I of course want to reuse.

Moreover I want to write minimal HTML-code as possible, but auto-generating 
fields does not work for me.

I currently try to solve these issues with a self-made Form class, which 
descends from form.Form. In case you are interested, here is my docstring 
which somehow explains the basic idea:

---------------- snip ---------------------

    """ A generic form class for rendering forms based on object data
    
    The class has the following key attributes:
    - widget_template_files: A sequence of widget template files that can be 
used
      in widgets to display a form field in a specific way
    - schema_fields: 
    - template: Same as the template attribute in form.Form, this specifies 
the template
      that should be used for rendering the page
    - schema_fields: a sequence of schema fields that can be copied from 
interfaces via
      the function "cloneField", e.g. cloneField(IFoo['bar']).
    
    When schema fields are created via the cloneField function, additional 
attributes can
    be set on the fields. The programmer has to make sure, that the names of 
the schema
    fields are distinct, hence in case schema fields have the same name, the 
__name__ attribute
    has to be set to a distinct name.
      
    Default values for fields can be automatically fetched and updated. How 
the mapping between
    the form fields and the data object is implemented, can either implicitly 
or explicitly
    defined.
    
    1) Explicit declaration:
    - If the schema field has the attribute "obj_attr", the specified 
attribute is used
      for reading/updating data. If the attribute does not exist, an error is 
raised
    - If the schema field has the attribute "obj_getter" or/and "obj_setter", 
the data
      object is queried for a matching method, which are used for 
getting/setting values.
      
    2) Implicit declaration:
    - If data object has methods beginning with "set_" and/or "get_" and match 
the
      "__name__" attribute of the schema field, these methods are 
automatically used
      for getting/setting values.

    The precedence is as follows:
    1) explicit getter/setter
    2) implicit getter/setter
    3) obj_attr
    
    """
------------------ snip -------------------

An example would look like this (cloneField does basically only a 
copy.deepcopy of the interface):

------------------- snip -------------------

    schema_fields = (
        cloneField(IFp['name1'], obj_attr = 'fp.name1'),
        cloneField(IFp['name2'], obj_attr = 'fp.name2'),
        cloneField(IFp['titel'], obj_attr = 'fp.titel'))

    template = ViewPageTemplateFile('fpform.pt')
    widget_template_files = ('widget_div.pt', 'widget_span.pt')

----------------- snip ---------------------

"widget_div.pt" has the common Zope3-HTML form code like this:

----------------- snip -----------------
<tal:block tal:define="widget python: options.get('widget', None)">
  <div class="label">

    <label for="field.name" title="The widget's hint"
        tal:attributes="for widget; title widget/hint"
        tal:content="widget/label">Label</label>
  </div>
  <div tal:condition="widget/error"
    tal:content="structure widget/error">Error</div>
  <div class="field">
      <input tal:replace="structure widget" />
  </div>
</tal:block>
------------- snip ---------------------

And "fpform.pt" is then very tidy:

------------ snip ----------------
<div tal:replace="structure view/widgets/name1/template_widget_div" />
<div tal:replace="structure view/widgets/name2/template_widget_div" />
<div tal:replace="structure view/widgets/titel/template_widget_div" />
------------ snip -----------------

My class has still various limitations, however, maybe Stephan Richters new 
form class offers some solutions but I until now I could not find time to 
have a look at it.

Anyway, in my case a decent ORM-integration with Zope3 forms is still a key 
issue to me.

Best Regards,
Hermann

-- 
x1 at aon.at
GPG key ID: 299893C7 (on keyservers)
FP: 0124 2584 8809 EF2A DBF9  4902 64B4 D16B 2998 93C7


More information about the Zope3-users mailing list