我正在编写一些测试,我需要在视图中使用模板而不使用文件(例如通过ViewPageTemplateFile
)。模板必须评估tal表达式并访问视图的功能。这是我目前的问题。我在评估PageTemplate中的view
时遇到错误。我不确定我的代码是否遵循最佳做法。
from plone.app.testing import TEST_USER_NAME, TEST_USER_PASSWORD
from plone.testing.z2 import Browser
from zope.component import getGlobalSiteManager
from zope.publisher.interfaces.browser import IBrowserView
from Products.Five.browser import BrowserView
from zope.pagetemplate.pagetemplate import PageTemplate
class MyView(BrowserView):
def __init__(self, context, request):
self.context = context
self.request = request
def render(self):
template = PageTemplate()
text = '''\
<div tal:on-error="string:view fails"><span tal:replace="view/var"/></div>
<div tal:on-error="string:python fails"><span tal:replace="python:'python works'"/></div>
'''
template.write(text)
return template()
def __call__(self):
return self.render()
def var(self):
return 'my_value'
global_site_manager = getGlobalSiteManager()
global_site_manager.registerAdapter(MyView, (None, None), IBrowserView, 'my_view')
browser=Browser(app.Plone)
browser.addHeader('Authorization',
'Basic %s:%s' % (TEST_USER_NAME, TEST_USER_PASSWORD))
browser.open(app.Plone.absolute_url() + '/@@my_view')
print browser.contents
产生以下输出:
<div>view fails</div>
<div>
python works
</div>
答案 0 :(得分:2)
到目前为止,我的解决方法是创建自己的class MyPageTemplate(PageTemplate)
,将视图的实例作为构造函数中的参数传递,并覆盖pt_getContext
以使用view
填充命名空间,来自实例的context
和request
。
我想知道是否有更好的解决方案(最佳做法)。
这是我的解决方法:
from plone.app.testing import TEST_USER_NAME
from plone.app.testing import TEST_USER_PASSWORD
from plone.testing.z2 import Browser
from zope.component import getGlobalSiteManager
from zope.publisher.interfaces.browser import IBrowserView
from Products.Five.browser import BrowserView
from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
from zope.pagetemplate.pagetemplate import PageTemplate
from zope.interface import Interface
from zope.publisher.browser import IDefaultBrowserLayer
class MyPageTemplate(PageTemplate):
instance = None
def __init__(self, instance):
self.instance = instance
def pt_getContext(self, instance, request, **kw):
namespace = super(MyPageTemplate, self).pt_getContext(**kw)
namespace['view'] = self.instance
namespace['context'] = self.instance.context
namespace['request'] = self.instance.request
return namespace
class MyView(BrowserView):
def __init__(self, context, request):
self.context = context
self.request = request
def render(self):
template = MyPageTemplate(self)
text = '''\
<div tal:on-error="string:request fails">request<span tal:replace="structure request"/> works</div>
<div tal:on-error="string:context fails">context/id=<span tal:replace="context/id"/> works</div>
<div tal:on-error="string:view fails">view/my_var=<span tal:replace="view/my_var"/> works</div>
<div tal:on-error="string:python fails"><span tal:replace="python:'python works'"/></div>
'''
template.write(text)
return template()
def __call__(self):
return self.render()
def my_var(self):
return 'my_value'
global_site_manager = getGlobalSiteManager()
global_site_manager.registerAdapter(MyView, (None, None), IBrowserView, 'my_view')
browser=Browser(app.Plone)
browser.addHeader('Authorization', 'Basic %s:%s' % (TEST_USER_NAME, TEST_USER_PASSWORD))
browser.open(app.Plone.absolute_url() + '/@@my_view')
print browser.contents