问题
We had a whole collection of Plone 3 sites with a custom Image type subclassed from ATImage. This allowed us to add an extra image scaling to the standard list ("'logo':(454, 58)", used by our theme package).
While this still works in Plone 4, it isn't really the correct approach now that plone.app.imaging is part of the standard toolkit. That can define custom scales on the fly.
It looks like I can enable plone.app.imaging on any type subclassed from ATImage by simply setting "sizes = None" for the collection of custom scales on the type. I am however then left with a redundant subclass of ATImage. Looking long term, it would be useful to replace all of our existing "FalconImage" content items (hundreds in total) with standard "Image" content items.
A brief experiment on a test site reveals that if I just walk through the document tree updating the portal_type attribute from "FalconImage" to "Image" then the content behaves as an "Image": each object suddenly acquires a Transform tab and all of the scales defined by @@imaging-controlpanel.
I am sure that there would be fallout from such a brute force approach. Is there a recommended approach for transforming one type into another?
(I'm happy to add source for our custom ATImage type if anyone thinks that it is relevant. It is really just a very minimal tweak of ATImage, with a different collection of sizes on the ImageField)
回答1:
Yes, there is a recommended approach:
http://pypi.python.org/pypi/Products.contentmigration
The only thing that you have to do is to write a custom migration from FalconImage to Image.
Bye, Giacomo
回答2:
You need to use Products.contentmigration but the docs there are no place to start. Use the docs at plone.org for a step-by-step on migrating content.
回答3:
Thanks to Giacomo and Ross for the pointers.
Just in case it is useful to others, my migration code ended up looking like the following:
from Products.contentmigration.walker import CustomQueryWalker
from Products.contentmigration.archetypes import InplaceATItemMigrator
class FalconImageMigrator(InplaceATItemMigrator):
walker = CustomQueryWalker
src_meta_type = "FalconImage"
src_portal_type = "FalconImage"
dst_meta_type = "ATBlob"
dst_portal_type = "Image"
# Following stolen from plone.app.blob.migrations, ATImageToBlobImageMigrator
# migrate all fields except 'image', which needs special handling...
fields_map = {
'image': None,
}
def migrate_data(self):
self.new.getField('image').getMutator(self.new)(self.old)
# ATFileToBlobMigrator reindexes certain fields. Otherwise we
# need to clear and rebuild the entire catalog.
def last_migrate_reindex(self):
self.new.reindexObject(idxs=['object_provides', 'portal_type',
'Type', 'UID'])
migrator = FalconImageMigrator
walker = migrator.walker(portal, FalconImageMigrator)
walker.go()
print walker.getOutput()
Complications:
Image is a little odd as a destination type, as data gets migrated into the blob store.
We need to update the catalog so that "resolveuid/UID" links generated by TinyMCE continue to work. last_migrate_reindex() method on Migrator class should be faster than clearing and rebuilding the entire catalog from scratch.
来源:https://stackoverflow.com/questions/7255932/migrating-from-now-obsolete-custom-atimage-content-type