Maurits van Rees wrote:
Hi,

The lib/python directory of a Zope instance seems to become a popular
place for putting things and rightfully so.  I can imagine that in a
few years time the Products dir becomes totally empty and that zope
only uses packages in lib/python.

I hope so. :)

But I wonder if there are (perhaps temporarily) downsides to that.
I bumped my toe the past week with two such issues:


1. zcml files are not loaded automatically.  This is no big deal
   really, as there are a few ways to solve this:

   - You can do an <include package="..." /> in a zcml file somewhere
     in the Products dir.

   - I heard ploneout does some hacking to the path to make sure these
     zcmls in lib/python get loaded too.

Nope.

But the plone.recipe.zope2instance recipe (like it's zope 3 equivalent) has an option 'zcml' where you can list package names for which ZCML slugs get installed automatically. This is not a hack. :)

The wider point here is that if you're working with eggs (and you will be, since third party products are starting to move to eggs) you probably want something a bit more egg-aware than dumb old instances. I strongly favour zc.buildout here, because it meets all those needs and makes sure the right packages (and the right packages only) are installed for Zope to run.

I keep promising more documentation on this (and I will, once I'm done with the book, which also covers it), but see this post:

http://www.nabble.com/forum/ViewPost.jtp?post=12284509&framed=y&skin=6741

   - You can put zcml "slugs" (one-liners) in etc/site.zcml or
     etc/package-includes/

The approach I prefer and advocate is to have *one* slug for a "policy" product (Wichert calls this a "deployment product"). This has a configure.zcml that includes other dependencies as and when needed. It also has an installation step that installs other packages as dependencies when the policy is installed from the quickinstaller.

Trust me - automatically loading things can lead to just as many headaches. Obviously, you want the core Plone stuff to load in lock-step, but sometimes other packages can do things that e.g. affect your package's tests or setup.

The main benefit I see of using eggs and non-flat namespaces is that it makes it much easier to manage things as sets of related packages, rather than big monoliths. $INSTANCE_HOME/Products/ was becoming *very* crowded, and people didn't split things up into more reusable, managable chunks. We saw that happen *a lot more* in the Plone 3 release, when people could create a package with paster. :)

See also: http://plone.org/documentation/how-to/use-paster

2. Translations from i18n and locales directories do not get loaded.
   You can add <i18n:registerTranslations directory="locales" /> and
   then that will get loaded, but this is done in a Zope 3 way that is
   not getting picked by the Zope 2 or Plone translation machinery.
   For starters, the po files do not get listed in the PTS in the
   Zope Control Panel.

   Plone 3.0 of course has templates in lib/python that need
   translations.  But those translations are in
   Products/PloneTranslations, so they get picked up as usual.

   So if you want to have a package in lib/python that needs
   translation, then you will also have to make a Product for the
   Products dir that contains the actual translations.

I'm not really too familiar with this. It sounds like a bug to me. :)

So I have two questions really:

A. Is there a way to have po files in lib/python get picked up by
   Zope 2 after all?

B. Are there more of these gotchas that developers should know?

When writing tests for packages that are also Zope 2 products, you can't use ZopeTestCase.installProduct('my.package'); the pattern I prefer is as follows:

http://dev.plone.org/collective/browser/borg/components/borg.project/trunk/borg/project/tests.py

That is:

- Any old-style products that need to be loaded for the test goes at module level as before:

ZopeTestCase.installProduct('RichDocument')

- After that, a *deferred method* is used to load packages. Note that this ONLY necessary if the package is a product, e.g. it uses <five:registerPackage /> to get skins, GS profiles or other product-like features. This can also be used to load specific ZCML files.

- Then, we call setupPloneSite() as normal, telling it to install any products (including packages that are products). Note that in Plone 3, this also works for packages without an Install.py, if they have a GS profile, you don't need to do a separate extension_profiles=[] argument.

This approach ensures that the package is loaded and installed only once for the test fixture, making tests much faster.

Martin

--
Acquisition is a jealous mistress


_______________________________________________
Product-Developers mailing list
[email protected]
http://lists.plone.org/mailman/listinfo/product-developers

Reply via email to