Re: [Zope3-Users] Transforming formlib field data on save

2008-01-22 Thread Marius Gedminas
On Tue, Jan 22, 2008 at 12:28:22PM +1300, andrew wrote:
 I'm struggling with how to transform some input data into an object
 property using an auto-generated formlib edit form, schema, etc. I see
 how the simple flow works, i.e.:
 
 1. Create a schema
 2. Build the form from the schema
 3. Use applyChanges to update context object properties with input data
 
 But what if I want to do something other than just set an object
 property ? In this case, I'm working on a content page editor where the
 underlying data is stored as the content of a page template, so I want
 to be able to map a form content field to / from the page template
 content instead of a property on the page template.

You can always write a custom action that stores the data wherever you
want.

class MyPage(form.EditForm):

form_fields = form.Fields(...)

actions = form.Actions() # remove the default Apply action

# and replace it with a custom one:
@form.action(_(Apply), condition=form.haveInputWidgets)
def apply_action(self, action, data):
self.context.pt_edit(data['content'])
self.status = _('Saved changes')

You can also combine manual actions with formlib's applyChanges, if you
want to -- just make sure you remove those fields you don't want formlib
to process from the data dict before you call applyChanges.

@form.action(_(Apply), condition=form.haveInputWidgets)
def apply_action(self, action, data):
self.context.pt_edit(data.pop('content'))
form.applyChanges(self.context, self.form_fields, data)
self.status = _('Saved changes')

I'm leaving some details (such as sending IObjectModified events, or not
doing anything if you haven't actually changed any of the values) as an
exercise for the reader.  Read the zope.formlib.form source code for
examples of that.

 Anyone got a simple example of how to go about this ? I'm guessing it's
 something to do with providing an adapter on the content field so I can
 override the get/set methods of the field, but I'm stuck at that point.

If you want to do it via adapters, here you go:

class ITemplateSource(Interface):
source = SourceText(title=uTemplate source)

class TemplateSource(object):
adapts(IMyTemplateInterface)
provides(ITemplateSource)

def __init__(self, context):
self.context = context

def _getSource(self):
return self.context.read()

def _setSource(self, new_source)
self.context.pt_edit(new_source, 'text/html')

source = property(_getSource, _setSource)

# Make sure to provideAdapter(TemplateSource) or the equivalent in
# ZCML for the following to work:

class MyPage(form.EditForm):

form_fields = form.Fields(..., ITemplateSource)

Since ITemplateSource.source is defined in the ITemplateSource
interface, formlib will try to adapt your context to ITemplateSource.

Disclaimer: all code in this email is untested.

HTH,
Marius Gedminas
-- 
An algorithm must be seen to be believed.
-- D.E. Knuth


signature.asc
Description: Digital signature
___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


[Zope3-Users] Transforming formlib field data on save

2008-01-21 Thread andrew
Hi All,

I'm struggling with how to transform some input data into an object
property using an auto-generated formlib edit form, schema, etc. I see
how the simple flow works, i.e.:

1. Create a schema
2. Build the form from the schema
3. Use applyChanges to update context object properties with input data

But what if I want to do something other than just set an object
property ? In this case, I'm working on a content page editor where the
underlying data is stored as the content of a page template, so I want
to be able to map a form content field to / from the page template
content instead of a property on the page template.

Anyone got a simple example of how to go about this ? I'm guessing it's
something to do with providing an adapter on the content field so I can
override the get/set methods of the field, but I'm stuck at that point.

Thanks,

Cheers, Andrew.



___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users