如何以编程方式访问 Plone 5 注册表中的资源列表

How to access programmatically the list of resources in Plone 5 registry

我正在为一些包编写测试,我需要验证是否正确注册了一些静态资源。

在 Plone 5 之前,我可以像这样访问资源注册表来做到这一点:

self.portal.portal_javascripts.getResourceIds()
self.portal.portal_css.getResourceIds()

如何在 Plone 5 中完成该任务?

看来答案就在 tests for resources in Products.CMFPlone.

具体来说,在该文件的测试用例中,有许多测试使用配置注册表来访问已注册的包和资源,如下所示:

from Products.CMFPlone.interfaces import IBundleRegistry
from Products.CMFPlone.interfaces import IResourceRegistry
from plone.registry.interfaces import IRegistry
from zope.component import getUtility

resources = getUtility(IRegistry).collectionOfInterface(
    IResourceRegistry, prefix="plone.resources"
)
bundles = getUtility(IRegistry).collectionOfInterface(
    IBundleRegistry, prefix="plone.bundles"
)

这些调用的 return 值是类似字典的对象,它们包含指向使用 registry.xml 通用设置导入步骤注册的捆绑包或资源的配置注册表条目的指针。

例如,如果您使用以下 xml 在您的产品中注册了一个捆绑包:

<records prefix="plone.bundles/my-product"
        interface='Products.CMFPlone.interfaces.IBundleRegistry'>
 <value key="resources">
  <element>my-resource</element>
 </value>
 <value key="enabled">True</value>
 <value key="jscompilation">++plone++static/my-compiled.js</value>
 <value key="csscompilation">++plone++static/my-compiled.css</value>
 <value key="last_compilation">2014-08-14 00:00:00</value>
</records> 

然后在由上面的资源注册表编辑的 bundles return 中,您将能够使用您的包的 "prefix" 中斜线后面的部分( 'my-product') 为您的包查找注册表记录代理,如下所示:

my_bundle = bundles['my-product']

该记录将提供对包定义接口的属性访问(有关详细信息,请参阅 Products.CMFPlone.interfaces.resources.IBundleRegistry)。因此,您应该能够检查它是否为已编译的 js 或 css:

设置了正确的值
assert my_bundle.jscompilation == '++plone++static/my-compiled.js'
assert my_bundle.csscompilation == '++plone++static/my-compiled.css'

注册资源的记录将以相同的方式工作,一个类似字典的对象,其键对应于 "prefix" 中斜线后 registry.xml 中的资源注册部分。在这种情况下 returned 的记录将支持 Products.CMFPlone.interfaces.resources.IResourceRegistry。但是您仍然可以使用属性访问来验证您期望的值是否已正确注册。

如果您有使用已弃用的 portal_javascriptportal_css 工具注册的资源(使用 jsregistry.xmlcssregistry.xml 通用设置导入步骤),关键是发现它们是 Plone 现在会自动将这些资源包含在一个名为 plone-legacy 的特殊包中。由于 bundle 有一个 resources 属性,它提供了该 bundle 中包含的资源列表,您应该可以这样做:

bundles = getUtility(IRegistry).collectionOfInterface(
    IBundleRegistry, prefix="plone.bundles"
)
legacy_bundle = bundles['plone-legacy']
assert "my-oldskool.js" in legacy_bundle.resources

这方面的例子也可以在 tests for resources in Products.CMFPlone 中找到。特别是在 TestResourceNodeImporter 测试用例中。

由于没有简单的方法来完成这个任务,而且所提出的解决方案增加了 10 多行代码,我想说这个测试必须在 Plone 5 中跳过:

IS_PLONE_5 = api.env.plone_version().startswith('5')

@unittest.skipIf(IS_PLONE_5, 'No easy way to test this under Plone 5')
def test_cssregistry(self):
    resource_ids = self.portal.portal_css.getResourceIds()
    self.assertIn(CSS, resource_ids)