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
deactivate
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/www.domain.com/Products/CMFPlone/FactoryTool.py", line 147, in __getitem__
File "/opt/zope/prd/www.domain.com/Products/CMFPlone/PloneFolder.py", line 399, in invokeFactory
File "/opt/zope/prd/www.domain.com/Products/CMFCore/TypesTool.py", line 934, in constructContent
File "/opt/zope/prd/www.domain.com/Products/CMFCore/TypesTool.py", line 343, in constructInstance
File "/opt/zope/prd/www.domain.com/Products/CMFCore/TypesTool.py", line 574, in _constructInstance
File "", line 4, in addImportedProject
File "/home/kees/zope-2.9.9/lib/python/OFS/ObjectManager.py", line 333, in _setObject
notify(ObjectAddedEvent(ob, self, id))
File "/home/kees/zope-2.9.9/lib/python/zope/event/__init__.py", line 23, in notify
subscriber(event)
File "/home/kees/zope-2.9.9/lib/python/zope/app/event/dispatching.py", line 66, in dispatch
for ignored in subscribers(event, None):
File "/home/kees/zope-2.9.9/lib/python/zope/component/__init__.py", line 181, in subscribers
return sitemanager.subscribers(objects, interface)
File "/home/kees/zope-2.9.9/lib/python/zope/component/site.py", line 89, in subscribers
return self.adapters.subscribers(required, provided)
File "/home/kees/zope-2.9.9/lib/python/zope/interface/adapter.py", line 481, in subscribers
subscribers = [subscription(*objects)
File "/home/kees/zope-2.9.9/lib/python/zope/app/event/objectevent.py", line 192, in objectEventNotify
adapters = subscribers((event.object, event), None)
File "/home/kees/zope-2.9.9/lib/python/zope/component/__init__.py", line 181, in subscribers
return sitemanager.subscribers(objects, interface)
File "/home/kees/zope-2.9.9/lib/python/zope/component/site.py", line 89, in subscribers
return self.adapters.subscribers(required, provided)
File "/home/kees/zope-2.9.9/lib/python/zope/interface/adapter.py", line 481, in subscribers
subscribers = [subscription(*objects)
File "/home/kees/zope-2.9.9/lib/python/OFS/subscribers.py", line 114, in dispatchObjectMovedEvent
callManageAfterAdd(ob, event.object, event.newParent)
File "/home/kees/zope-2.9.9/lib/python/OFS/subscribers.py", line 144, in callManageAfterAdd
ob.manage_afterAdd(item, container)
File "/opt/zope/prd/www.domain.com/Products/Archetypes/BaseFolder.py", line 88, in manage_afterAdd
File "/opt/zope/prd/www.domain.com/Products/CMFCore/CMFCatalogAware.py", line 202, in manage_afterAdd
File "/opt/zope/prd/www.domain.com/Products/Archetypes/CatalogMultiplex.py", line 34, in indexObject
File "/opt/zope/prd/www.domain.com/Products/I18NFolder/patches.py", line 281, in catalog_object
File "/opt/zope/prd/noorderlink/client0/Products/CacheSetup/patch.py", line 100, in catalog_object
File "/opt/zope/prd/noorderlink/client0/Products/CacheSetup/patch_utils.py", line 6, in call
File "/home/kees/zope-2.9.9/lib/python/Products/ZCatalog/ZCatalog.py", line 567, in catalog_object
update_metadata=update_metadata)
File "/home/kees/zope-2.9.9/lib/python/Products/ZCatalog/Catalog.py", line 339, in catalogObject
index = self.updateMetadata(object, uid)
File "/home/kees/zope-2.9.9/lib/python/Products/ZCatalog/Catalog.py", line 277, in updateMetadata
newDataRecord = self.recordify(object)
File "/home/kees/zope-2.9.9/lib/python/Products/ZCatalog/Catalog.py", line 416, in recordify
attr=getattr(object, x, MV)
File "/opt/zope/prd/www.domain.com/Products/CMFPlone/CatalogTool.py", line 99, in __getattr__
File "/opt/zope/prd/www.domain.com/Products/CMFPlone/CatalogTool.py", line 206, in getObjSize
File "/opt/zope/prd/www.domain.com/Products/Archetypes/BaseObject.py", line 583, in get_size
File "/opt/zope/prd/www.domain.com/Products/Archetypes/Field.py", line 1311, in get_size
File "/opt/zope/prd/www.domain.com/Products/Archetypes/Field.py", line 1305, in getBaseUnit
File "/opt/zope/prd/www.domain.com/Products/Archetypes/Field.py", line 1278, in get
File "/opt/zope/prd/www.domain.com/Products/Archetypes/Field.py", line 1033, in _wrapValue
File "/opt/zope/prd/www.domain.com/Products/Archetypes/Field.py", line 1168, in _make_file
File "/opt/zope/prd/www.domain.com/Products/Archetypes/BaseUnit.py", line 34, in __init__
File "/opt/zope/prd/www.domain.com/Products/Archetypes/BaseUnit.py", line 56, in update
File "/opt/zope/prd/www.domain.com/Products/MimetypesRegistry/MimeTypesRegistry.py", line 370, in __call__
File "/opt/zope/prd/www.domain.com/Products/MimetypesRegistry/MimeTypesRegistry.py", line 319, in classify
File "/opt/zope/prd/www.domain.com/Products/MimetypesRegistry/mime_types/mtr_mimetypes.py", line 82, in classify
File "/usr/lib/python2.4/sre.py", 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 plone.app.form on Plone 2.5

This is probably not good enough for a how-to on plone.org, but worthwile recording anyway. I had a bit of a hard time installing plone.app.form 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 plone.app.form for Plone 2.5 from http://svn.plone.org/svn/plone/plone.app.form/branches/plone-2.5. The instructions don't tell you to build an egg from this, like so: python2.4 setup.py 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 http://plone.org/documentation/how-to/zope-python-packages-using-easy_install. Then you can activate your workingenv, and use easy_install, except you don't easy_install plone.app.form, but you point easy_install to your created egg: easy_install-2.4 /path/to/dist/plone.app.form*.egg. It'll probably complain about a site.py 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 plone.app.form 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):
"""
"""
security.declarePublic('sayHello')
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/Install.py, 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 plone.org.