Mounting content from one ZEO storage into an existing Plone site
Storages
We'll use 2 filestorages, one called segmented, which will contain our plone site and a second one called subsegment that will be mounted to our plone site. These are the 2 definitions from ZEO_HOME/etc/zeo.conf:
...
<filestorage segmented>
path $INSTANCE/var/segmented.fs
</filestorage>
<filestorage subsegment>
path $INSTANCE/var_nobackup/subsegment.fs
</filestorage>
...
Mount main site
Our main site will be mounted in a folder called 'mainpage' directly located in our zope root directory. For those of you who used ZEO storages before, this won't be anything new:
<zodb_db segmented>
mount-point /mainpage
cache-size 5000
<zeoclient>
server localhost:8100
storage segmented # name of remote storage (lower case!!!)
name segmented # local name of remote storage
var $INSTANCE/var # path for temporary cache file
</zeoclient>
</zodb_db>
We mount the segmented storage to /mainpage by adding a 'ZODB Mount Point' via ZMI
(don't forget to check "Create new folders if the mounted objects don't yet exist").
In /mainpage we'll create a plone site called 'plone'.
Mount subsegments
Now let's come to the tricky part: Within the plonesite we just created we want to have a folder 'subsegment' that is physically stored in our subsegment database
You'd probably try the same as i did first:
<zodb_db subsegment>
mount-point /mainpage/plone/subsegment
pool-size 10
cache-size 500
<zeoclient>
server localhost:8100
storage subsegment
name subsegment
var $INSTANCE/var
</zeoclient>
</zodb_db>
When we now add the ZODB mount point an ordinary zope folder named subsegment will be created within our plonesite. This folder is not visible in the navtree and you can't add content to it using the plone interface.
So we need to tell zope to create ATFolder objects, because those will play nicely with our plonesite. Fortunately we can specify the type of folder created using the container-class directive:
<zodb_db subsegment>
mount-point /mainpage/plone/subsegment
container-class Products.ATContentTypes.content.folder.ATFolder
pool-size 10
cache-size 500
<zeoclient>
server localhost:8100
storage subsegment
name subsegment
var $INSTANCE/var
</zeoclient>
</zodb_db>
after deleting the subsegment folder and restarting zope we can add the mountpoint and let zope create the folders again...
But what?? Again, subsegment is a plain zope folder - Arghhhhh! What happened?
ATFolder can't be used as container-class because of it's dependencies to the reference system [1] The product MountFolder fixes this issues by providing a type that can be used as container-class and works with plone too. (See [1] for more information)
However, we don't want to use yet another content type just to be able to mount our subsegment storage.
Creating a 'subsegment' ATFolder TTP in /mainpage/plone/ prevents the subsegment mount point from beeing mounted:
/mainpage segmented Ok
/mainpage/plone/subsegment subsegment ** Something is in the way **
Workaround
In the archive of the german zope user group we can find an interesting discussion [2] and solution for this problem.
To provide our ATFolder a context he can "live with" we create an empty filestorage mount it to /empty and create a PloneSite and a ATFolder in it:
<filestorage empty>
path $INSTANCE/var_nobackup/empty.fs
</filestorage>
<zodb_db empty>
mount-point /empty
cache-size 500
<zeoclient>
server localhost:8100
storage empty
name hallo
var $INSTANCE/var
</zeoclient>
</zodb_db>
Stop zope and zeo and copy empty.fs into subsegment.fs. Now you might say "Hey, this won't work! Empty used another mountpoint..."
You are right in the second point, but zope can mount filestorages to a virtual path using the syntax `mount-point virtual_path:real_path`:
<zodb_db subsegment>
mount-point /mainpage/plone/subsegment:/empty/plone/subsegment
container-class Products.ATContentTypes.content.folder.ATFolder
pool-size 10
cache-size 500
<zeoclient>
server localhost:8100
storage subsegment
name subsegment
var $INSTANCE/var
</zeoclient>
</zodb_db>
Thanks to this virtual_path:real_path notation the plonesite and the ATFolder created
in /empty could also be called 'mysite' and 'myfolder'.
You can now access and work with the ATFolder under /mainpage/plone/subsegment.
Update the Catalog
To make content in subsegement show up in the navtree you have index all the objects in the freshly mounted database!
An ordinary 'Update Catalog' (ZMI/portal_catalog | Advanced) does not do the job because it's only updating all indexes on all currently indexed objects.
Clearing the catalog (ZMI/portal_catalog | Advanced) and find and catalog all types (ZMI/portal_catalog | Find Objects) is not good practice either, because tools and other stuff you certainly don't need/want in your catalog get indexed too.
Plone 2.1.3 and above offer you a rebuild tab in portal_catalog (similar to uid_catalog and reference_catalog). For rebuilding your catalog in Plone versions <= 2.1.2 i wrote a handy script [3]that let's you rebuild the whole catalog or index objects below a certain one recursively (without clearing the catalog)
Resources
- [1] MountFolder Readme
- http://dev.plone.org/collective/browser/MountFolder/trunk/README.txt
- [2] ZODB Mount Point container-class ATFolder
- http://www.dzug.org/mailinglisten/zope/archive/2005/2005-05/1115225556901
- [3] Script for rebuilding the catalog
- https://svn.webmeisterei.com/repos/public/plone-tools/rebuild_catalog/trunk/
