一些試驗和錯誤之後,事實證明這是可能的:
from zope.container.interfaces import INameChooser
from zope.component.hooks import getSite
from plone.dexterity.factory import DexterityFactory
class CustomDexterityFactory(DexterityFactory):
def __call__(self, *args, **kw):
folder = DexterityFactory.__call__(self, *args, **kw)
# we are given no context to work with so need to resort to getSite
# hook or zope.globalrequest.getRequest and then wrap the folder
# in the context of the add view
site = getSite()
wrapped = folder.__of__(site["PUBLISHED"].context)
# invokeFactory fails if the container has no id
folder.id = "tmp_folder_id"
# standard AT content creation
wrapped.invokeFactory("Page", "tmp_obj_id")
page = wrapped["tmp_obj_id"]
new_id = INameChooser(service_obj).chooseName(title, page)
page.setId(new_id)
page.setTitle(title)
# empty the id, otherwise it will keep
folder.id = None
return folder
雖然上述作品,在某些點上創建頁面編入索引(也許invokeFactory),這意味着將有假進入目錄。刪除條目的代碼可以添加到工廠中。
總的來說,只需創建一個事件處理程序就比較容易了,正如@keul在他的回答中所建議的那樣。
當你說獲取portal_types失敗時,我懷疑你缺少某種收購包裝;這可能是在錯誤的地方做到這一點的一個症狀(例如,IObjectCreatedEvent中新創建的基於敏捷度的文件夾沒有父項並且尚未包裝)。使用IObjectAddedEvent應該可以工作,因爲你應該有一個已經包裝好的對象(參見keul的答案)。 – sdupton
是的,敏捷通過沒有要求或任何種類的情況下工廠,所以沒有收購包裝。 – Petri