Author Archive

Using plone.app.form in Plone 2.5

It’s really nice that so much zope 3 stuff is available already in Plone 2.5 and Five 1.4. I use formlib and plone.app.form with success. I found three issues, but after solving them it works nicely.

  1. I had an “AttributeError: debug” error when trying to use formlib. The cause was that Zope 3 has a debug attribute on requests, while Zope 2 doesn’t. When my widget (in the form) rendered itself, which is zope 3 code, it tried to use the debug attribute on the request, but as the request is a Zope 2 request it couldn’t be found. I fixed this by monkey patching ZPublisher.HTTPRequest and setting the debug attribute to zope.publisher.base.DebugFlags(). I’m told this will be fixed, but as I want this to work now I’ll use the patch for now.
  2. If using latest trunk of plone.app.form one should inherit from Five’s EditForm. In earlier versions one needed to inherit directly from zope.formlib’s EditForm, otherwise you couldn’t save forms. plone.app.form did some monkey patching. I’m glad Daniel Nouri changed this behaviour. One should now inherit from Five’s base classes, not directly from zope.formlib’s base classes.
  3. formlib is supposed to work, but not all widgets are supported. The OrderedMultiSelectWidget is rendering itself and therefore it’s using the Zope 3 page template engine. The Zope 3 page template engine is not supported in Zope 2. When a path expression (which the template for the widget contains) is traversed it tries to adapt to ITraversable. This will not work in Five as this traverses the url, not path expressions. So the solution is to provide another adapter. The result is that the default Zope 3 adapter for traversing path expressions will be used (for input widgets).

<adapter

for=”zope.app.form.browser.interfaces.IInputWidget”
provides=”zope.app.traversing.interfaces.ITraversable”
factory=”zope.app.traversing.adapters.DefaultTraversable”

/>

Not sure if 1 and 3 are still valid for Five 1.5.

Conditional adapters

There are use cases when you just want to adapt an object if some condition is true. For instance I wanted to adapt xml-rpc requests only if they were meant for my application, so I wouldn’t interfere with other packages that may use xml-rpc. I found it was rather easy (after figuring out how :) to make a conditional adapter. Here’s a simple example that can be run in a zope prompt (zopectl debug).

First we have some imports, basic interfaces and classes.

from zope.interface import Interface, implements, implementer
from zope.component import adapts, adapter, provideAdapter
class IA(Interface):
pass
class A(object):
implements(IA)
x=7
class IB(Interface):
pass

An adapter class for adapting objects providing IA to IB would typically look like this:

class AdapterAtoB(object):
implements(IB)
adapts(IA)
def __init__(self, context):
....self.context = context

After registering this adapter one would be able to adapt objects providing IA to IB:

provideAdapter(AdapterAtoB)
>>> a = A()
>>> b = IB(a)

But let’s say you want the adapter lookup to succeed only when A.x = 7, then you would need to do something like this:

class AdapterAtoB(object):
implements(IB)
#we don't need adapts anymore
def __init__(self, context):
....self.context = context
@adapter(IA)
@implementer(IB)
def a_to_b(obj):
if obj.x == 7:
....return AdapterAtoB(obj)
else:
....return None
>>> provideAdapter(a_to_b)
>>> a = A()
>>> b = IB(a)
>>> a.x = 2
b = IB(a)
TypeError: ('Could not adapt', <A object at ...>, <InterfaceClass IB>)

Mission accomplished.

(had problems with indenting, that’s why the dots are there)

Changing file encoding with Vim

I found a web page that showed a few funky characters. It must be an encoding problem so I thought about how to fix this. This is how I did.

First I wanted to know how the template file was encoded. To do that I opened Vim and ran “:set fileencoding”. Vim displayed “latin1″. To make the file utf-8 I ran “:set fileencoding=utf-8″ and saved it. The web page looked ok after that.
To verify the encoding one can use a hex editor. I used khexedit (KDE program) to see what my funny character was in hex. Before I changed the encoding the character was E5 in hex. Python can verify that å should be E5:

>>> u’å’.encode(’latin1′)
‘\xe5′

So the encoding is latin1. To verify that vim changed the file correctly one can check with khexedit after changing the file. khexedit now showed C3 A5 for this character. Checking with python again:

>>> u’å’.encode(’utf-8′)
‘\xc3\xa5′

C3 A5 seems to be correct hex for the å character in utf-8 encoding, so know I can be certain Vim did the right thing.