基于hurry.resource的Grok资源
项目描述
megrok.resource 是一个旨在将 hurry.resource 和 z3c.hashedresource 集成到 Grok 应用程序中的软件包。
设置
让我们导入并初始化必要的工作环境
>>> import grokcore.component as grok >>> from zope.testbrowser.testing import Browser >>> browser = Browser() >>> browser.handleErrors = False
库
库是一个组件,旨在公开包含资源的文件夹
>>> from megrok import resource >>> class SomeCSS(resource.Library): ... resource.path('ftests/css') >>> grok.testing.grok_component('somecss', SomeCSS) True
一旦被 grokked,库提供 ILibrary 接口并获取一个可访问的名称
>>> from megrok.resource import ILibrary >>> ILibrary.providedBy(SomeCSS) True >>> SomeCSS.name 'somecss'
此时,它应通过组件架构作为命名适配器访问
>>> from zope.component import getAdapter >>> from zope.publisher.browser import TestRequest >>> library = getAdapter(TestRequest(), name='somecss') >>> library <grokcore.view.components.DirectoryResource object at ...>
资源
简单资源
资源可以作为其库的一部分声明,包括其依赖项
>>> css_a = resource.ResourceInclusion(SomeCSS, 'a.css') >>> css_b = resource.ResourceInclusion(SomeCSS, 'b.css')
分组资源
有时,资源需要按逻辑分组。它们可以在组包含中声明
>>> css_group = resource.GroupInclusion([css_a, css_b]) >>> css_group.inclusions() [<ResourceInclusion 'a.css' in library 'somecss'>, <ResourceInclusion 'b.css' in library 'somecss'>]
库资源
有时,单独声明资源和库可能过于繁琐。当资源不打算重复使用时,可能会觉得使用单个声明来注册一切很有吸引力。在这些情况下,您需要的是 ResourceLibrary 组件。
资源库是库和组包含的组合。您需要定义通常的路径和名称,然后是链接的资源
>>> class EasyResources(resource.ResourceLibrary): ... resource.path('ftests/css') ... resource.resource('a.css') ... resource.resource('b.css') >>> grok.testing.grok_component('someresources', EasyResources) True
一旦组件被 grokked,资源即可使用
>>> EasyResources.inclusions() [<ResourceInclusion 'a.css' in library 'easyresources'>, <ResourceInclusion 'b.css' in library 'easyresources'>]
组件中包含资源
在渲染网页时,我们希望能够在需要的位置包含资源。
有几种包含资源的方法。可以在任何IResourcesIncluder组件上自动遍历,或者手动指定。
遍历包含
在这个例子中,我们将创建一个视图并使用自动包含,使用include指令
>>> from grokcore import view >>> from zope.interface import Interface >>> class MyView(view.View): ... grok.context(Interface) ... resource.include(css_a) ... ... def render(self): return ""
为了在遍历时自动包含资源,我们需要通知发布机制,我们的组件(视图)是一个IResourcesIncluder。这在使用“include”指令时会自动完成
>>> resource.IResourcesIncluder.implementedBy(MyView) True
当然,这不应删除现有的接口实现
>>> from zope.interface import Interface >>> class IMySuperIface(Interface): pass >>> class MyView(view.View): ... grok.context(Interface) ... grok.implements(IMySuperIface) ... resource.include(css_a) ... ... def render(self): return "<html><head></head></html>" >>> resource.IResourcesIncluder.implementedBy(MyView) True >>> IMySuperIface.implementedBy(MyView) True
如果需要包含多个资源,include指令可以嵌套
>>> class AnotherView(MyView): ... resource.include(css_a) ... resource.include(css_b) >>> grok.testing.grok_component('AnotherView', AnotherView) True >>> browser.open('https://127.0.0.1/@@anotherview') >>> print browser.contents <html><head> <link... href="https://127.0.0.1/@@/++noop++.../somecss/a.css" /> <link... href="https://127.0.0.1/@@/++noop++.../somecss/b.css" /> </head></html>
ResourceLibrary组件可以像普通资源一样包含
>>> class YetAnotherView(view.View): ... grok.context(Interface) ... resource.include(EasyResources) ... ... def render(self): ... return u"<html><head></head></html>" >>> grok.testing.grok_component('yav', YetAnotherView) True >>> browser.open('https://127.0.0.1/@@yetanotherview') >>> print browser.contents <html><head> <link... href="https://127.0.0.1/@@/++noop++.../easyresources/a.css" /> <link... href="https://127.0.0.1/@@/++noop++.../easyresources/b.css" /> </head></html>
包含验证
如果提供的值不是有效的包含对象,include指令将引发错误
>>> sneaky = object() >>> class FailingView(view.View): ... grok.context(Interface) ... resource.include(sneaky) ... ... def render(self): ... return u"" Traceback (most recent call last): ... ValueError: You can only include IInclusion or ResourceLibrary components.
它应该接受非解析的ResourceLibraries作为有效的包含
>>> class OtherResources(resource.ResourceLibrary): ... resource.path('ftests/css') ... resource.resource('a.css') >>> class TolerantView(view.View): ... grok.context(Interface) ... resource.include(OtherResources) ... ... def render(self): ... return u""
远程包含
到目前为止,我们已经看到可以使用include指令进行资源包含。然而,能够在不“拥有”的类上设置包含也是非常有用的。这种“远程”包含是通过使用component_includes函数实现的。
我们首先注册一个不包含资源的视图
>>> class DummyView(view.View): ... grok.context(Interface) ... ... def render(self): ... return u"<html><head></head></html>" >>> grok.testing.grok_component('dummy', DummyView) True
视图类不实现所需的接口
>>> resource.IResourcesIncluder.implementedBy(DummyView) False
现在,我们可以使用远程包含函数来启用资源
>>> resource.component_includes(DummyView, css_group) >>> resource.IResourcesIncluder.implementedBy(DummyView) True >>> resource.include.bind().get(DummyView) [<hurry.resource.core.GroupInclusion object at ...>]
此函数可以在类或实例上使用
>>> class UselessView(view.View): ... grok.context(Interface) ... ... def render(self): return u"" >>> grok.testing.grok_component('useless', UselessView) True >>> from zope.component import getMultiAdapter >>> useless = getMultiAdapter( ... (object(), TestRequest()), name="uselessview") >>> useless <megrok.resource.ftests.UselessView object at ...> >>> resource.component_includes(useless, css_group) >>> resource.IResourcesIncluder.providedBy(useless) True >>> resource.include.bind().get(useless) (<hurry.resource.core.GroupInclusion object at ...>,)
缓存和哈希
你可能注意到了资源URL中的“++noop++”遍历器,这是用来提供哈希和因此唯一的URL。这对于与缓存一起工作以及避免提供过时的资源非常有用。
然而,这种行为(默认情况下)可能是不希望的。要禁用使用哈希URL,我们可以使用use_hash指令并将其值设置为False。这可以在类定义中或通过使用set方法来完成
>>> from megrok.resource import use_hash >>> use_hash.set(SomeCSS, False) >>> browser.open('https://127.0.0.1/@@anotherview') >>> print browser.contents <html><head> <link... href="https://127.0.0.1/@@/somecss/a.css" /> <link... href="https://127.0.0.1/@@/somecss/b.css" /> </head></html>
变更日志
0.5 (2010-07-24)
删除了特定的ILibrary接口,现在使用hurry.resource中的接口,因此找到的ILibraryUrl适配器对megrok.resource.Library和hurry.resource.Library都是相同的。您需要hurry.zoperesource 0.5才能为hurry.resource.Library实例提供哈希资源。
0.4.1 (2010-02-19)
修复了在同一个包中使用“include”指令包含ResourceLibrary的情况。这会引发错误,因为非解析的ResourceLibrary不提供IInclusion。现在,指令会检查值的子类以确定给定的包含是否是有效的IInclusion或ResourceLibrary子类。
0.4 (2010-02-18)
清理了依赖项:一切都被声明得恰到好处。《zope.site》现在是一个主要依赖项,而不是测试依赖项。
将模块“traversal”重命名为“url”,以更准确地描述该模块的内容:URL计算。
hurry.resource中的“mode”现在由包公开。
0.3 (2009-12-23)
使用include指令时,IResourcesIncluder接口现在由类自动实现。这使得整个系统更加自然。
接口已移动到专用模块。如果您以前从components导入,请修改您的代码。
0.2 (2009-12-22)
添加了一个ResourceLibrary组件,它是Library和GroupInclusion的混合。它允许在单个类中声明Library和资源,但会影响可重用性。
Library现在直接继承自grokcore.view.DirectoryResource,以继承get方法的行为。为了避免grokkers冲突(grokcore.view.DirectoryResource grokker没有为name指令提供回退),我们的grokker现在具有优先级并明确设置了name指令的值。
0.1 (2009-12-21)
初始版本
项目详情
megrok.resource-0.5.zip 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 07934ec4c0082e3a583de045bc910ce47ed153f6b39543d28956779fed75deae |
|
MD5 | 2062d2d761e3c72b838c7e9ac64ff765 |
|
BLAKE2b-256 | 4c874ed20aed4749809aacec0c8860c84429ac9238042f26d2ca0fb9efab6699 |