[Zope-CMF] A widget for image fields

Charlie Clark charlie at begeistert.org
Thu Mar 4 14:16:21 EST 2010


Hi,

after a tax inspection this morning I decided I deserved some coding this  
afternoon so I worked on something I've long been interested in but not  
quite sussed: a formlib widget for Image fields which always display the  
image in an edit view and do not overwrite it on form submission. The  
rationale behind this for having an image field as part of an object say a  
profile and without continuing to subclass OFS.Image.

On the first point I don't think there is anyway around a hack in formlib  
because formlib fields are not traversable - you cannot have a request  
directly on the field to display something. I think this restriction may  
be one of the reasons for z3c.form. I think the workaround of a dedicated  
view for the object say MyProfile/image which just streams the image data  
is _tolerable_ if far from perfect.

On the second it really is unexpected behaviour to have you binary data  
wiped if you don't resubmit it - formlib will always default to None.

This is my workaround:

 from zope.app.form.browser.textwidgets import FileWidget

class ImageWidget(FileWidget):
     """Widget for image fields. Will try and display the image if  
possible."""

     template = ViewPageTemplateFile("widget.pt")

     def __call__(self):
         extra = ""
         if getattr(self.context.context, self.context.__name__, None):
             extra = self.template()
         return extra + super(ImageWidget, self).__call__()

     def _toFieldValue(self, input):
         if input is None or input == '':
             value = self.context.missing_value
         try:
             seek = input.seek
             read = input.read
         except AttributeError, e:
             raise ConversionError(_('Form input is not a file object'), e)
         else:
             seek(0)
             data = read()
             if data or getattr(input, 'filename', ''):
                 value = data
             elif hasattr(self.context.context, self.context.__name__):
                 value = getattr(self.context.context,  
self.context.__name__)
             else:
                 value = self.context.missing_value
         return value

Does anyone else have a use for this? If so I'd like to get it into shape  
to be included. Thoughts and comments much appreciated.

Charlie
-- 
Charlie Clark
Helmholtzstr. 20
Düsseldorf
D- 40215
Tel: +49-211-938-5360
GSM: +49-178-782-6226


More information about the Zope-CMF mailing list