Today, I've spent a lot of time trying to use z3c.formext into plone.
Here is a summary of the different adaptations to be done to make this 


* in the file,  the statement used into the getConfig 
function of the Component class in not compatibe with Python2.4. (simple 
      return jsonEncode(self._getConfig()) if json else self._getConfig()

   must be replaced by

       if json:
           return jsonEncode(self._getConfig())
       return self._getConfig()

* I also have modified calls to the translate method to provide the 
request as context since, in zope2, locale is set up on the request.
def translateObject(o, context):
     if isinstance(o, list):
         for index, value in enumerate(o):
             o[index] = translateObject(value, context)
     elif isinstance(o, tuple):
         o = [translateObject(value, context) for value in o]
     elif isinstance(o, dict):
         for key, value in o.items():
             o[key] = translateObject(value, context)
     elif isinstance(o, unicode):
         o = translate(o, context=context)
     return o

def jsonEncode(o, context):
     o = translateObject(o, context)
     return encode(o)

* the handler used for the jsmodule zcml directive doesn't correctly 
register the resource for zope2. To make the resource available, I've 
modified the directive to use the same implementation that the one used 
by Five.  I can provide the new implementation into a new module (maybe 
plone.z3cformext or collective.z3cformext or ???)

* the versionedResource zcml directive doen't work for me. I've just 
registered the z3c.formext.loader.js as a simple browser:resource (it's 
probably the same kind of problem that for the jsmodule directive.


z3c.formjs is used to provide ajax functionalities used for button 
These functionalities are provided by an AjaxRequestTraverserPlugin that 
allow to access methods registered as an ajax request handler (ex button 
These handler are provided as BrowserPage that allow these to be 
The AjaxRequestTraverserPlugin has to be rewritten since our z3c.form 
instance are wrapped into a Five BrowserView by plone.z3cform.
The AjaxView must also be rewritten to mix in acquisition so that 
security can be acquired for views.
My changes look like:

     class AJAXView(Acquisition.Explicit, BrowserPage):
         """A wrapper class around AJAX handler to allow it to be 

             Mixes in explicit acquisition so that security can be 
acquired for

         def __init__(self, handler, request, view):
             self.context = self.handler = handler
             self.request = request
             self.__parent__ = self.view = view
             #see line 284 needed to build a physicalPath.
             #it's probably not the good way
             self.__name__ = self.handler.func.__name__

         def __call__(self):
             return self.handler(self.view)

     class AJAXRequestTraverserPlugin(object):
         """Allow access to methods registered as an ajax request handler.

         Call acquisition


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

         def publishTraverse(self, request, name):
             #context is a plone.z3cform.layout.FormWrapper
             #a call to switch_on' is required before we can
             #update and use the form_instance
             handler = 
             if handler is None:
                 raise NotFound(self.context, name, request)
             return AJAXView(handler, self.request,


The new implementation can be provided into a new module 
(plone.z3cformjs or collective.z3cformjs or ???)
The taverser plugin would be registered as a subscriber for the 
plone.z3cform.interfaces.IFormWrapper or a new interface defined in the 
new module




The factory used to provide the ajax traverser plugin is provided by 
The traversing process in zope2 is implemented into 
ZPublisher.BaseRequest. The PluggableBrowserTraverser is looked up by 
the traverseName method (line 308).
After the lookup, an explicit call to the Acquisition is performed
   def traverseName(self, ob, name):
         if name and name[:1] in '@+':
             # Process URI segment parameters.
             ns, nm = nsParse(name)
             if ns:
                     ob2 = namespaceLookup(ns, nm, ob, self)
                 except TraversalError:
                     raise KeyError(ob, name)
                 return ob2.__of__(ob)
Since the PluggableBrowserTraverser provided by  z3c.traverser is not 
Acquisition.Explicit, we need to provide a new one mixin the 
z3c.traverser.browser.PluggableBrowserTraverser and Acquisition.Explicit.
The new traverser can be registered as an adapter for the 
plone.z3cform.interfaces.IFormWrapper or the new interface provided by 
(plone.z3cformjs or collective.z3cformjs or ???)

The new implementation can be provided into a new module 
(plone.z3ctraverser or collective.z3ctraverser or ???) or we can use the 
plone.z3cformjs module

into the plone.z3cformjs configure.zcml, the factory used for ajax would 
be registered with


It's possible to use z3c.formext with Plone/zope2. Maybe, some of my 
explanations are wrong and I've missed something... Your comments are 
I'm really impressed by the concepts and the functionalities provided by 
the different modules involved into the integration of z3c.formext. 
Thank you to their authors and contributors! The Plone community has 
much to learn from what is done outside of itself... Plone

sorry for my English....

ps: I think that the z3cFormPanel extjs component uses the svn version 
of extjs (probably the next 3.0). If you use extjs 2.2 you have to 
modify some parts of the z3cFormPanel definition.

Zope3-users mailing list

Reply via email to