[Zope] Local FS manage_addFolder woes

Jonothan Farr jfarr@real.com
Mon, 1 May 2000 19:13:19 -0700


> LocalFS does not make use of the standard ZODB manage methods. It has its
> own methods to do everything. I once discussed that with Jonothan
>   (the coder of Local FS) and he thinks (if I understood him correctly)
> that for some reasons it is inappropriate to make use of these methods,
> since the objects contained in LocalFS really do not exist in the ZODB nor
> have a similar state.

Well, I've been pretty hard-headed about not implementing the objectValues
family of ObjectManager methods in the LocalDirectory object because it solves
some very specific problems. Other than that I strive to reuse existing Zope
interfaces, logic, and code as much as possible.

The basic explanation for this problem is this. The manage_addFolder is an
attribute of the Folder module. Just about every built-in Zope object and add-in
product implements its own set of manage_addXXX methods. It would be prohibitive
for me to try to duplicate them all in the LocalFS product. The Zope machinery
actually adds all of these methods to the Folder object when it loads all of the
products. I can't use the same technique because I don't know which order my
product will be loaded in relation to the other products.

The reason you can add folders using the management interace is because the
LocalDirectory object implements _setObject. Here's basically what happens:

- You select the Folder option from the Add form on the management screen.
- This calls the manage_addProduct method of the LocalDirectory object with the
value of "OFSP/folderAdd" (view source on the management screen to see how this
is done).
- manage_addProduct is technically not a method, it is a ProductDispatcher class
instance, which is is implemented in App/FactoryDispatcher.py. The
ProductDispatcher works its magic which basically redirects you to the folderAdd
DTML method, which is implemented in OFS/folderAdd.dtml.
- You submit the form, whose action is manage_addFolder. This manage_addFolder
is an attribute of the Folder object that contains the LocalFS object. However,
the 'self' argument passed to the method is the LocalDirectory object.
- manage_addFolder creates a new Folder object and calls self._setObject to add
it to 'self'.
- This calls the _setObject method of the LocalDirectory object, which sees that
the meta-type of the object is 'Folder', so it creates a directory in the local
file system and all that jazz.

The reason your DTML method doesn't work when it calls manage_addFolder is
because the method is acquired from the containing folder, as you suspected, and
because when manage_addFolder is called, the 'self' parameter is also the
containing folder, so the call to self._setObject adds the new folder to the
Folder object instead of the LocalDirectory object. The self parameter is passed
automagically by the Zope machinery, and is not affected by using dtml-with. If
you ask me, this is one of several serious problems with the current dtml-with
implementation.

Whew. Now that I've explained more than you ever wanted to know about the
workings of the LocalDirectory management interface, here's a workaround:
implement your dtml method as a local file with a .dtml extension and put it in
the directory where you want to add files. Unfortunately, this will only allow
you to add files to that directory.

A better fix is to write an external method.

Example:

from OFS.Folder import Folder

def addFolder(self, id, title=''):
  ob = Folder()
  ob.id = id
  ob.title = title
  self._setObject(id, ob)

Then from DTML use:

<dtml-call "addFolder(localFSobject, folderNameVar)">

Sorry if that was more information than you needed. Hope this helps you solve
your problem.

--jfarr