跳转到主要内容

基于hurry.resource的Grok资源

项目描述

megrok.resource 是一个旨在将 hurry.resourcez3c.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 (25.5 kB 查看哈希值)

上传时间

由以下机构支持