2012-07-26 57 views
3

我想以编程方式进行一些注册,这些注册取决于存储在plone.app.registry中的数据。具体而言,我想将menuItems添加到通常通过zcml完成的对象的显示菜单中。如何在启动时初始加载plone站点时订阅

这种“plone loaded”事件的“标准”方法是什么?

途径,我认为是:

  • 使用站点根目录遍历前钩,使注册,然后设置某种标记,以防止重新注册
  • 倾听一个Zope启动事件(如zope.processlifetime.IProcessStarting),然后找到在ZODB所有的Plone站点并进行注册

回答

3

我会使用一个事件处理程序挂接到现场穿越,具有一个切换:

_menuItemsRegistered = set() 

def beforeSiteTraverse(site, event, _handled=set()): 
    if site.getPhysicalPath() not in _handled: 
     registerMenuItems(site) 
     __handled.add(site.getPhysicalPath()) 

现在registerMenuItems将只对每个Plone站点执行一次,而且执行起来非常便宜。

如果您只需要为每个实例处理一个Plone网站,您可以减少这个(更多)第一次开火后取消订阅您的处理程序。

这工作比处理一个IProcessStarting事件作为,那么你就必须成立本地注册(调用setSite)对每一个Plone站点之前,你甚至可以访问注册表工具更好。

+0

感谢您的回答。我也意识到,我需要处理注册表中的设置在运行时更改的情况,那么menuItems也需要更改。我说的像menuItem这样的注册是每个线程吗?在这种情况下,我不知何故需要在每个线程上重新安装我的menuItems。所以我认为beforeSiteTraverse需要查看数据库中的时间戳或散列,以确定menuItems是否仍然有效。这是否会执行?有没有更好的方法来做到这一点? – djay 2012-07-27 01:15:07

+0

听起来像你需要重新考虑这整个设置,并使用动态菜单?在任何情况下,组件注册都不是每个线程,尽管它们可能会被每个线程缓存。并且持久保存本地组件注册表,然后应用通常的落实边界和每个线程对象实例缓存。 – 2012-07-27 08:03:29

相关问题