HTML布局引擎

z3c.layout的Python项目详细描述


HTML布局引擎

这个包实现了一个基于静态html的页面呈现模型 通过映射内容从外部动态生成的文档 HTML文档树中位置的提供程序定义。这是 称为“布局”。

组件架构用于提供扩展点 使其应用广泛。支持使用 zope.contentprovider呈现方案(更新/呈现)。

静态资源,如HTML文档(图像, 包括样式表和javascript文件 作为浏览器资源发布(请参见zope.app.publisher.browser)。

优点:

  • 不需要模板语言
  • 支持两阶段渲染
  • 与创造性工作流程集成
  • 柔性扩展点

穿行

布局和区域

让我们从实例化一个布局开始。我们将手动执行此操作 为了演示,通常使用 zcml指令<;浏览器:布局>;。

>>> from z3c.layout.model import Layout
>>> layout = Layout(
...     "test", "%s/templates/default/index.html" % test_path, "test")

注册资源目录。

>>> import zope.configuration.config as config
>>> context = config.ConfigurationMachine()
>>> from zope.app.publisher.browser import resourcemeta
>>> resourcemeta.resourceDirectory(
...     context, "test", "%s/templates/default" % test_path)
>>> context.execute_actions()

布局通过定义一个或多个区域而动态化。他们是 使用xpath表达式和插入映射到html位置 模式,它是“replace”、“append”、“prepend”、“before”或 “之后”。

区域可以直接指定内容提供商的名称,也可以 依赖于自适应来生成内容提供程序组件。我们会 研究这两种方法:

>>> from z3c.layout.model import Region

首先,我们定义一个标题区域,直接指定 内容提供商。

>>> title = Region("title", ".//title", title=u"Title", provider="title")

然后是一个内容区域,我们把它留给内容提供者 部件自适应。

>>> content = Region("content", ".//div", "Content")

为了在布局中注册它们,我们只需添加它们。

>>> layout.regions.add(title)
>>> layout.regions.add(content)

让我们定义一个上下文类。

>>> class MockContext(object):
...     interface.implements(interface.Interface)

我们需要提供一个可以提供内容的通用适配器 不直接指定区域的提供程序。作为 例如,我们将定义一个适配器,该适配器仅尝试查找内容 与区域同名的提供程序。

>>> from z3c.layout.interfaces import IContentProviderFactory
>>> class EponymousContentProviderFactory(object):
...     interface.implements(IContentProviderFactory)
...
...     def __init__(self, region):
...         self.region = region
...
...     def __call__(self, context, request, view):
...         name = self.region.name
...         return component.getMultiAdapter(
...            (view.context, request, view), IContentProvider, name)
>>> from z3c.layout.interfaces import IRegion
>>> component.provideAdapter(
...     EponymousContentProviderFactory, (IRegion,))

渲染

在呈现布局之前,我们需要注册内容提供者 对于这两个地区。我们将使用一个模拟类来演示。

>>> from zope.contentprovider.interfaces import IContentProvider
>>> class MockContentProvider(object):
...     interface.implements(IContentProvider)
...
...     __name__ = u""
...
...     def __init__(self, *args):
...         pass
...
...     def update(self):
...         pass
...
...     def render(self):
...         return self.__name__
...
...     def __repr__(self):
...         return "<MockContentProvider '%s'>" % self.__name__
>>> from zope.publisher.interfaces.browser import IBrowserRequest
>>> from zope.publisher.interfaces.browser import IBrowserView
>>> component.provideAdapter(
...     MockContentProvider, (MockContext, IBrowserRequest, IBrowserView),
...     name="title")
>>> component.provideAdapter(
...     MockContentProvider, (MockContext, IBrowserRequest, IBrowserView),
...     name="content")

让我们实例化布局浏览器视图。我们必须定义一个上下文 并提出请求。

>>> from zope.publisher.browser import TestRequest
>>> context = MockContext()
>>> request = TestRequest()

我们需要请求是可注释的。

>>> from zope.annotation.attribute import AttributeAnnotations
>>> component.provideAdapter(
...     AttributeAnnotations, (TestRequest,))

视图希望上下文适应ILayout

>>> from z3c.layout.interfaces import ILayout
>>> component.provideAdapter(
...     lambda context: layout, (MockContext,), ILayout)
>>> from z3c.layout.browser.layout import LayoutView
>>> view = LayoutView(context, request)

验证布局视图是否能够访问这些提供程序。

>>> view.mapping
{'content':
 (<Region 'content' .//div (replace) None>, <MockContentProvider 'content'>),
 'title':
 (<Region 'title' .//title (replace) 'title'>, <MockContentProvider 'title'>)}

现在是实际产出。

>>> print view()
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html>
<head>
<link rel="stylesheet" href="test/main.css" type="text/css" media="screen">
<title>title</title>
</head>
<body>
    <div id="content">content</div>
  </body>
</html>

转换

在需要使用python转换 静态HTML文档在编译时,一个或多个转换可能是 定义。

>>> from z3c.layout.model import Transform

让我们添加一个将语言设置添加到<;html>;-标记的转换。

>>> def set_language(node):
...     node.attrib["lang"] = "en"
>>> layout.transforms.add(
...    Transform(set_language))
>>> layout.parse().getroot().attrib["lang"]
'en'

以及另一个将类分配给<;body>;-标记的转换。

>>> def set_class(node, value):
...     node.attrib["class"] = value
>>> layout.transforms.add(
...    Transform(lambda body: set_class(body, "front-page"), ".//body"))
>>> layout.parse().xpath('.//body')[0].attrib["class"]
'front-page'

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
java如何隐藏actionbar和显示选项卡   java将触摸事件从回收器传递到其父LinearLayout   springboot应用程序中的java enable XFrameOptions标头(不含spring security)   java将十进制128序列化为JSON   java将给定时间转换为GMT   java如何解决SSL握手异常   java哪些平台的缓冲区大小有限?   java如何使用IDE在storm production集群中提交拓扑   Android Javaİmageview的进展   JAVA网使用Spring PathMatchingResourcePatternResolver时出现URI语法异常   java如果有人试图访问我的JSP页面,如何首先显示登录页面?   带水平滚动的java嵌套回收视图   java有可能将Hashmap get和put结合起来吗?   java为什么在计算两毫秒时间戳之间的差时使用模运算符?   从字符串Java中提取葡萄牙语日期   java为什么dispatchTouchEvent避免在屏幕上单击?