启动时首次加载plone站点时如何订阅

启动时首次加载plone站点时如何订阅,plone,Plone,我想根据plone.app.registry中存储的数据以编程方式进行一些注册。具体来说,我想将菜单项添加到对象的显示菜单中,这通常是通过zcml完成的 对于这种“plone加载”事件,什么是“标准”方法 我考虑过的方法有: 在站点根上使用预遍历钩子,进行注册,然后设置某种类型的标记以防止重新注册 侦听zope启动事件(如zope.processlifetime.IProcessStarting),然后在ZODB中查找所有Plone站点并执行注册 我会使用一个事件处理程序来钩住站点遍历,并使用

我想根据plone.app.registry中存储的数据以编程方式进行一些注册。具体来说,我想将菜单项添加到对象的显示菜单中,这通常是通过zcml完成的

对于这种“plone加载”事件,什么是“标准”方法

我考虑过的方法有:

  • 在站点根上使用预遍历钩子,进行注册,然后设置某种类型的标记以防止重新注册
  • 侦听zope启动事件(如zope.processlifetime.IProcessStarting),然后在ZODB中查找所有Plone站点并执行注册

我会使用一个事件处理程序来钩住站点遍历,并使用一个切换:

_menuItemsRegistered = set()

def beforeSiteTraverse(site, event, _handled=set()):
    if site.getPhysicalPath() not in _handled:
        registerMenuItems(site)
        __handled.add(site.getPhysicalPath())
现在,
registerNuItems
对于每个Plone站点只执行一次,而且执行起来非常便宜

如果每个实例只需处理一个Plone站点,则可以(更进一步)减少这种情况;只需在第一次开火后取消你的处理程序


这比处理
IProcessStarting
事件更有效,因为在访问注册表实用程序之前,您必须在每个Plone站点上设置本地注册表(调用
setSite
)。我还意识到,我需要处理注册表中的设置在运行时发生更改的情况,然后菜单项也需要更改。我说像menuItems这样的注册是每个线程的,对吗?在这种情况下,我需要在每个线程上重新安装menuItems。因此,我认为beforeSiteTraverse需要查看数据库中的时间戳或散列,以确定menuItems是否仍然有效。这会表演吗?有更好的方法吗?听起来你需要重新考虑整个设置,使用动态菜单来代替?在任何情况下,组件注册都不是每个线程的,尽管它们可能是每个线程缓存的。本地组件注册表被持久化,然后应用通常的提交边界和每线程对象实例缓存。