1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
|
import os
from zope.component.zcml import handler
from zope.component.interface import provideInterface
from zope.configuration.exceptions import ConfigurationError
from zope.configuration.fields import GlobalObject
from zope.configuration.fields import Path
from zope.interface import Interface
from zope.interface import implements
from zope.interface import classProvides
from zope.schema import TextLine
from repoze.bfg.interfaces import IRequest
from repoze.bfg.interfaces import IViewFactory
from repoze.bfg.interfaces import IViewPermission
from repoze.bfg.interfaces import IView
from repoze.bfg.template import Z3CPTTemplateFactory
from repoze.bfg.template import render_template
from repoze.bfg.security import ViewPermissionFactory
class TemplateOnlyView(object):
implements(IView)
classProvides(IViewFactory)
template = None
def __init__(self, context, request):
self.context = context
self.request = request
def __call__(self, **kw):
if self.template is None:
raise ValueError('a "template" attribute must be attached to '
'a TemplateOnlyView')
kw = dict(view=self, context=self.context, request=self.request,
options=kw)
return render_template(self.template, **kw)
def __repr__(self):
klass = self.__class__
return '<%s.%s object at %s for %s>' % (klass.__module__,
klass.__mame__,
id(self),
self.template)
class TemplateOnlyViewFactory(object):
""" Pickleable template-only view factory """
implements(IViewFactory)
def __init__(self, template):
self.template = template
def __call__(self, context, request):
factory = TemplateOnlyView(context, request)
factory.template = self.template
return factory
def view(_context,
permission=None,
for_=None,
factory=None,
name="",
template=None,
):
if (template and factory):
raise ConfigurationError(
'One of template or factory must be specified, not both')
if template:
template_abs = os.path.abspath(str(_context.path(template)))
if not os.path.exists(template_abs):
raise ConfigurationError('No template file named %s' % template_abs)
utility = Z3CPTTemplateFactory(template_abs)
_context.action(
discriminator = ('utility', IView, template_abs),
callable = handler,
args = ('registerUtility', utility, IView, template_abs),
)
factory = TemplateOnlyViewFactory(template_abs)
if not factory:
raise ConfigurationError(
'Neither template nor factory was specified, though one must be '
'specified.')
if for_ is not None:
_context.action(
discriminator = None,
callable = provideInterface,
args = ('', for_)
)
if permission:
pfactory = ViewPermissionFactory(permission)
_context.action(
discriminator = ('permission', for_,name, IRequest,IViewPermission),
callable = handler,
args = ('registerAdapter',
pfactory, (for_, IRequest), IViewPermission, name,
_context.info),
)
_context.action(
discriminator = ('view', for_, name, IRequest, IViewFactory),
callable = handler,
args = ('registerAdapter',
factory, (for_, IRequest), IViewFactory, name,
_context.info),
)
class IViewDirective(Interface):
for_ = GlobalObject(
title=u"The interface or class this view is for.",
required=False
)
permission = TextLine(
title=u"Permission",
description=u"The permission needed to use the view.",
required=False
)
factory = GlobalObject(
title=u"Class",
description=u"A class that provides a __call__ used by the view.",
required=False,
)
name = TextLine(
title=u"The name of the page (view)",
description=u"""
The name shows up in URLs/paths. For example 'foo' or
'foo.html'.""",
required=False,
)
template = Path(
title=u"The name of a template that implements the page.",
description=u"""Refers to a file containing a z3c.pt page template""",
required=False
)
|