允许将视图代码与皮肤模板(如z3c.viewtemplate)分离,但也允许将多个模板插入到视图代码中。
z3c.pluggabletemplates的Python项目详细描述
这个包裹有两件事。首先,它执行z3c.viewtemplate所做的所有操作 –将视图代码层与模板外观层分离。第二,它 允许无限数量的模板插入到任何视图类中。
这是干什么的?
使母版变得简单是一项艰巨的工作。使用宏对于 要对付的设计师。实际上他们没有。使用z3c.viewtemplate和viewlets 对于程序员来说是相当复杂的。事实上我没有。所以 是允许设计师和程序员共同工作的另一个进化步骤 不一定了解对方,甚至不喜欢对方。
这项工作在很大程度上依赖于jurgen为z3c.viewtemplate所做的工作代码。
一个简单的母版页实现
这是一个不使用pluggabletemplates的简单母版页实现。
browser.py:
class MyView(object): masterpage = ViewTemplateFile('templates/masterpage.pt') subpage = ViewTemplateFile('templates/content.pt') authors = ['Roger Zelazny', 'Isaac Asimov', 'Robert Heinlien', 'J.R.R Tolkein'] def __call__(self): return masterpage() templates/masterpage.pt:: <html>... <body> <h2>My Master Page</h2> <span tal:replace="view/subpage" /> </body> </html> templates/index.pt:: <ul> <li tal:repeat="author view/authors" tal:content="author" /> </ul>
这是一个非常容易遵循的模式,可以相当容易地扩展。这个 当您想要更改皮肤时,模式会遇到直接的问题。更换皮肤 应该和++skin++design1…+++skin++design2一样简单,但是要做到这一点,所有的 视图代码需要重复。这是可以做到的,但是只要有一张照片 代码已更改,所有其他视图代码都必须修补,并且很容易从 同步。
输入viewplugs
design1/configure.zcml:
<browser:pluggableTemplates for="myapp.browser.MyView" layer=".skins.Design1" > <template name="master" file="templates/masterpage.pt" /> <template name="subtemplate" file="templates/subtemplate.pt /> </browser:pluggableTemplates>
所以这是否意味着我们需要为 ++皮肤++设计2??不一定:
class Design2(Design1): """ Skin marker """
现在您可以使用++skin++design1 one作为基础并简单地重写 需要更改的视图或模板等。样式表和 图像。
通过将模板插入视图代码,每个模板可以显示 其他模板:
<span tal:replace="view/template1" /> <span tal:replace="view/template2" />
当然,所有视图属性都可用:
<span tal:replace="view/myattr1" />
不过,您可以添加任意多的视图,但添加的视图太多,可能会重新进行复制。
博士学位
在使用此新方法设置视图组件之前,必须先 创建主模板和子模板…
>>> import os, tempfile >>> temp_dir = tempfile.mkdtemp() >>> master = os.path.join(temp_dir, 'master.pt') >>> open(master, 'w').write('''<h2>Masterpage</h2><span tal:replace="view/subtemplate"/>''') >>> subtemplate = os.path.join(temp_dir, 'subtemplate.pt') >>> open(subtemplate, 'w').write('''This is the subtemplate: <span tal:replace="view/taste" />''') >>> from zope.publisher.browser import TestRequest >>> request = TestRequest()>>> from zope import interface >>> from z3c.pluggabletemplates.baseview import MasterView >>> from z3c.pluggabletemplates.pagetemplate import RegisteredPageTemplate >>> class IMyView(interface.Interface): ... pass >>> class MyView(MasterView): ... interface.implements(IMyView) ... master = RegisteredPageTemplate( 'master' ) ... taste = 'success' ... subtemplate = RegisteredPageTemplate( 'subtemplate' )>>> view = MyView(root, request)
由于模板尚未注册,因此呈现视图将失败:
>>> print view() Traceback (most recent call last): ... ComponentLookupError: ......
现在注册模板(通常使用zcml):
>>> from zope import component >>> from zope.publisher.interfaces.browser import IDefaultBrowserLayer >>> from z3c.pluggabletemplates.zcml import TemplateFactory >>> from zope.pagetemplate.interfaces import IPageTemplate
模板工厂允许我们创建viewpagetemplatefile实例:
>>> factory = TemplateFactory(master, 'text/html')
我们在视图界面和层上注册工厂:
>>> component.provideAdapter(factory, ... (interface.Interface, IDefaultBrowserLayer), ... IPageTemplate, name="master") >>> mastertemplate = component.getMultiAdapter( ... (view, request), IPageTemplate, name="master" ) >>> mastertemplate <zope.app.pagetemplate.viewpagetemplatefile.ViewPageTemplateFile ...> >>> factory = TemplateFactory(subtemplate, 'text/html')
我们在视图界面和层上注册工厂:
>>> component.provideAdapter(factory, ... (interface.Interface, IDefaultBrowserLayer), ... IPageTemplate, name="subtemplate") >>> subtemplate = component.getMultiAdapter( ... (view, request), IPageTemplate, name="subtemplate" ) >>> subtemplate <zope.app.pagetemplate.viewpagetemplatefile.ViewPageTemplateFile ...>
现在我们有了默认层的注册模板,我们可以调用 再次查看:
>>> print view() <h2>Masterpage</h2>This is the subtemplate: success <BLANKLINE>
清理
>>> import shutil >>> shutil.rmtree(temp_dir)
修订日志
- 2006年3月11日首次入住