Friday, August 29, 2008

Plone won't start after installing i18ndude

To generate a generated.pot file from your uml diagram, ArchGenXML can use i18ndude if that module is installed in python.
When i installed i18ndude in my system-wide python2.4 (the same one used by Zope) using easy_install, at least one of my Zope/Plone instances wouldn't start afterwards. This is because i18ndude installs all kinds of dependency eggs. One solution is to just remove all these extra eggs after you install i18ndude: Go to site-packages and remove the eggs that were installed at the same time as i18ndude.
Another, i think better, way is to use virtualenv. in my ~/bin directory, i created a directory for AGX called archgenxml-virtualenv. I virtualenv'ed this directory and installed archgenxml and i18ndude in it. Last, i made a symlink from my ~/bin directory to the AGX executable and the i18ndude executable.
To sum it up:

sudo apt-get install virtualenv
mkdir ~/bin
cd ~/bin
mkdir archgenxml-virtualenv
virtualenv archgenxml-virtualenv
. archgenxml-virtualenv/bin/activate
easy_install archgenxml
easy_install i18ndude
ln -s archgenxml-virtualenv/bin/archgenxml .
ln -s archgenxml-virtualenv/bin/i18ndude .

Thursday, August 28, 2008

Translating a content type's name

So you have created a nice MyProduct-xx.po file, but how to translate the names of your custom content-types? This goes outside the MyProduct-domain. Place a MyProduct-plone-xx.po in your i18n directory, with domain set to "plone". And just enter strings and translations.

May also be used to override Plone's default translations.

Tuesday, August 19, 2008

A mysterious error solved (TypeError: expected string or buffer)

Today, I ran into an error message when creating a new object. The object was going to be an instance of "ImportedObject", which i created with ArchGenXML. Here is the traceback:

2008-08-19 11:51:27 ERROR Plone
Traceback (most recent call last):
File "/opt/zope/prd/", line 147, in __getitem__
File "/opt/zope/prd/", line 399, in invokeFactory
File "/opt/zope/prd/", line 934, in constructContent
File "/opt/zope/prd/", line 343, in constructInstance
File "/opt/zope/prd/", line 574, in _constructInstance
File "", line 4, in addImportedProject
File "/home/kees/zope-2.9.9/lib/python/OFS/", line 333, in _setObject
notify(ObjectAddedEvent(ob, self, id))
File "/home/kees/zope-2.9.9/lib/python/zope/event/", line 23, in notify
File "/home/kees/zope-2.9.9/lib/python/zope/app/event/", line 66, in dispatch
for ignored in subscribers(event, None):
File "/home/kees/zope-2.9.9/lib/python/zope/component/", line 181, in subscribers
return sitemanager.subscribers(objects, interface)
File "/home/kees/zope-2.9.9/lib/python/zope/component/", line 89, in subscribers
return self.adapters.subscribers(required, provided)
File "/home/kees/zope-2.9.9/lib/python/zope/interface/", line 481, in subscribers
subscribers = [subscription(*objects)
File "/home/kees/zope-2.9.9/lib/python/zope/app/event/", line 192, in objectEventNotify
adapters = subscribers((event.object, event), None)
File "/home/kees/zope-2.9.9/lib/python/zope/component/", line 181, in subscribers
return sitemanager.subscribers(objects, interface)
File "/home/kees/zope-2.9.9/lib/python/zope/component/", line 89, in subscribers
return self.adapters.subscribers(required, provided)
File "/home/kees/zope-2.9.9/lib/python/zope/interface/", line 481, in subscribers
subscribers = [subscription(*objects)
File "/home/kees/zope-2.9.9/lib/python/OFS/", line 114, in dispatchObjectMovedEvent
callManageAfterAdd(ob, event.object, event.newParent)
File "/home/kees/zope-2.9.9/lib/python/OFS/", line 144, in callManageAfterAdd
ob.manage_afterAdd(item, container)
File "/opt/zope/prd/", line 88, in manage_afterAdd
File "/opt/zope/prd/", line 202, in manage_afterAdd
File "/opt/zope/prd/", line 34, in indexObject
File "/opt/zope/prd/", line 281, in catalog_object
File "/opt/zope/prd/noorderlink/client0/Products/CacheSetup/", line 100, in catalog_object
File "/opt/zope/prd/noorderlink/client0/Products/CacheSetup/", line 6, in call
File "/home/kees/zope-2.9.9/lib/python/Products/ZCatalog/", line 567, in catalog_object
File "/home/kees/zope-2.9.9/lib/python/Products/ZCatalog/", line 339, in catalogObject
index = self.updateMetadata(object, uid)
File "/home/kees/zope-2.9.9/lib/python/Products/ZCatalog/", line 277, in updateMetadata
newDataRecord = self.recordify(object)
File "/home/kees/zope-2.9.9/lib/python/Products/ZCatalog/", line 416, in recordify
attr=getattr(object, x, MV)
File "/opt/zope/prd/", line 99, in __getattr__
File "/opt/zope/prd/", line 206, in getObjSize
File "/opt/zope/prd/", line 583, in get_size
File "/opt/zope/prd/", line 1311, in get_size
File "/opt/zope/prd/", line 1305, in getBaseUnit
File "/opt/zope/prd/", line 1278, in get
File "/opt/zope/prd/", line 1033, in _wrapValue
File "/opt/zope/prd/", line 1168, in _make_file
File "/opt/zope/prd/", line 34, in __init__
File "/opt/zope/prd/", line 56, in update
File "/opt/zope/prd/", line 370, in __call__
File "/opt/zope/prd/", line 319, in classify
File "/opt/zope/prd/", line 82, in classify
File "/usr/lib/python2.4/", line 134, in search
return _compile(pattern, flags).search(string)
TypeError: expected string or buffer

When i renamed the field 'update' on this class to 'myUpdate', it works fine. So clearly 'update' is a name to avoid for your fields. It would be interesting to keep a list somewhere of all unwise choices for field names.

Friday, August 15, 2008

How to install on Plone 2.5

This is probably not good enough for a how-to on, but worthwile recording anyway. I had a bit of a hard time installing on Plone 2.5. It's required by slideshowfolder 4.0, which has some nice extra features compared to 1.2.2.

Like the instructions in slideshowfolder 4.0 told me, i got for Plone 2.5 from The instructions don't tell you to build an egg from this, like so: python2.4 bdist_egg The egg will go in the dist/ directory.

The best way to install this in your Zope instance (not in your system-wide python2.4) is to create a workingenv for your instance, as indicated in Then you can activate your workingenv, and use easy_install, except you don't easy_install, but you point easy_install to your created egg: easy_install-2.4 /path/to/dist/*.egg. It'll probably complain about a already being there, just remove it and run easy_install again.

Finally, do modifications to $INSTANCE_HOME/etc/site.zcml, $INSTANCE_HOME/etc/site-packages/configure.zcml and $INSTANCE_HOME/etc/site-packages/overrides.zcml as indicated in the checkout's docs/INSTALL.txt.

Friday, August 8, 2008

Using /profiles/default/structure with custom folderish type: 'Could not adapt'

Using ArgoUML and ArchGenXML, I created a special type ImportedProjectsFolder to hold items of type ImportedProject. I did this by just giving it a stereotype of <<folder>> or <<large>>. Although this did give me the required folderish type, Generic Setup did not want to create the folder: on installing the product, it said:

('Could not adapt', , ) 
The solution was to not use a stereotype, but to use a generalisation from ATFolder (<<stub>>). This way, the ImportedProjectsFolder inherited the required interface implementation, and installation was succesful.

Tuesday, August 5, 2008

Why does Plone say "404 Not Found" when i call my tool's method?

Tool methods must have a docstring, at least if you want to call them through the web! You may have seen some docstrings in Plone that say "This method is called TTW, so it needs a docstring". Today I tried this method:

class MyTool(UniqueObject, SimpleItem, Persistent):
def sayHello(self):
"""Say something
return 'Hello!'

which only started working when I remembered that line and added the docstring.

Friday, August 1, 2008

Adding a custom permission to a Plone 2.5 product

Figuring out how to register a new permission in a Zope product took me some time. Here's how i did it: In Extensions/, put this::

from Products.CMFCore.permissions import setDefaultRoles

def install(self, reinstall=False):
setDefaultRoles('MyProduct: MyPermission', ())

And that's all i have to say about that.

Edit: This is now a how-to on