/
components.py
131 lines (109 loc) · 4.3 KB
/
components.py
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
##############################################################################
#
# Copyright (c) 2006-2007 Zope Foundation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Grok components"""
from operator import itemgetter
from zope import component, interface
from zope.viewlet.manager import ViewletManagerBase
from zope.viewlet.viewlet import ViewletBase
from grokcore.viewlet import interfaces, util
@interface.implementer(interfaces.IViewletManager)
class ViewletManager(ViewletManagerBase):
template = None
def __init__(self, context, request, view):
super(ViewletManager, self).__init__(context, request, view)
self.context = context
self.request = request
self.view = view
self.__name__ = self.__view_name__
static_name = getattr(self, '__static_name__', None)
if static_name is not None:
self.static = component.queryAdapter(
self.request,
interface.Interface,
name=static_name)
else:
self.static = None
def sort(self, viewlets):
"""Sort the viewlets.
``viewlets`` is a list of tuples of the form (name, viewlet).
"""
# Sort viewlets following grok.order rule.
return util.sort_components(viewlets, key=itemgetter(1))
def default_namespace(self):
namespace = {}
namespace['context'] = self.context
namespace['request'] = self.request
namespace['static'] = self.static
namespace['view'] = self.view
namespace['viewletmanager'] = self
return namespace
def namespace(self):
return {}
def update(self):
super(ViewletManager, self).update()
# Filter out the unavailable viewlets *after* the viewlet's update()
# has been called.
self.viewlets = [v for v in self.viewlets if v.available()]
def render(self):
"""See zope.contentprovider.interfaces.IContentProvider"""
# Now render the view
if self.template:
return self.template.render(self)
else:
return u'\n'.join([viewlet.render() for viewlet in self.viewlets])
# Mark the render() method as a method from the base class. That
# way we can detect whether somebody overrides render() in a subclass.
render.base_method = True
class Viewlet(ViewletBase):
"""Batteries included viewlet.
"""
def __init__(self, context, request, view, manager):
super(Viewlet, self).__init__(context, request, view, manager)
self.context = context
self.request = request
self.view = view
self.viewletmanager = manager
self.__name__ = self.__view_name__
static_name = getattr(self, '__static_name__', None)
if static_name is not None:
self.static = component.queryAdapter(
self.request,
interface.Interface,
name=static_name)
else:
self.static = None
def default_namespace(self):
namespace = {}
namespace['context'] = self.context
namespace['request'] = self.request
namespace['static'] = self.static
namespace['view'] = self.view
namespace['viewlet'] = self
namespace['viewletmanager'] = self.manager
return namespace
def namespace(self):
return {}
def update(self):
pass
def available(self):
"""Return True if this viewlet is to be rendered. False otherwise.
Note that the available() method is called *after* update() but
*before* render() has been called.
"""
return True
def render(self):
return self.template.render(self)
# Mark the render() method as a method from the base class. That
# way we can detect whether somebody overrides render() in a subclass.
render.base_method = True