index 81d10ac83241ffca52207c118d09dd2c57195395..1de56e1ce1d42b1503959af6015915b1961f6203 100644 (file)
}
# add in the item if there is one
if client.nodeid:
- c['context'] = HTMLItem(client, classname, client.nodeid)
+ if classname == 'user':
+ c['context'] = HTMLUser(client, classname, client.nodeid)
+ else:
+ c['context'] = HTMLItem(client, classname, client.nodeid)
else:
c['context'] = HTMLClass(client, classname)
return c
if self._v_errors:
raise PageTemplate.PTRuntimeError, \
- 'Page Template %s has errors.' % self.id
+ 'Page Template %s has errors.'%self.id
# figure the context
classname = classname or client.classname
# we want config to be exposed
self.config = client.db.config
+ def __getitem__(self, item):
+ self._client.db.getclass(item)
+ return HTMLClass(self._client, item)
+
def __getattr__(self, attr):
try:
- self._client.db.getclass(attr)
+ return self[attr]
except KeyError:
raise AttributeError, attr
- return HTMLClass(self._client, attr)
+
def classes(self):
l = self._client.db.classes.keys()
l.sort()
l.append(cl.lookup(entry))
return l
-class HTMLClass:
+class HTMLPermissions:
+ ''' Helpers that provide answers to commonly asked Permission questions.
+ '''
+ def is_edit_ok(self):
+ ''' Is the user allowed to Edit the current class?
+ '''
+ return self._db.security.hasPermission('Edit', self._client.userid,
+ self._classname)
+ def is_view_ok(self):
+ ''' Is the user allowed to View the current class?
+ '''
+ return self._db.security.hasPermission('View', self._client.userid,
+ self._classname)
+ def is_only_view_ok(self):
+ ''' Is the user only allowed to View (ie. not Edit) the current class?
+ '''
+ return self.is_view_ok() and not self.is_edit_ok()
+
+class HTMLClass(HTMLPermissions):
''' Accesses through a class (either through *class* or *db.<classname>*)
'''
def __init__(self, client, classname):
self._client = client
self._db = client.db
- # we want classname to be exposed
- self.classname = classname
+ # we want classname to be exposed, but _classname gives a
+ # consistent API for extending Class/Item
+ self._classname = self.classname = classname
if classname is not None:
self._klass = self._db.getclass(self.classname)
self._props = self._klass.getprops()
klass = HTMLUser
else:
klass = HTMLItem
- l = [klass(self._client, self.classname, x) for x in self._klass.list()]
+
+ # get the list and sort it nicely
+ l = self._klass.list()
+ sortfunc = make_sort_function(self._db, self.classname)
+ l.sort(sortfunc)
+
+ l = [klass(self._client, self.classname, x) for x in l]
return l
def csv(self):
# use our fabricated request
return pt.render(self._client, self.classname, req)
-class HTMLItem:
+class HTMLItem(HTMLPermissions):
''' Accesses through an *item*
'''
def __init__(self, client, classname, nodeid):
def __getitem__(self, item):
''' return an HTMLProperty instance
'''
- #print 'HTMLItem.getitem', (self, item)
+ #print 'HTMLItem.getitem', (self, item)
if item == 'id':
return self._nodeid
# used for security checks
self._security = client.db.security
+
_marker = []
def hasPermission(self, role, classname=_marker):
''' Determine if the user has the Role.
classname = self._default_classname
return self._security.hasPermission(role, self._nodeid, classname)
+ def is_edit_ok(self):
+ ''' Is the user allowed to Edit the current class?
+ Also check whether this is the current user's info.
+ '''
+ return self._db.security.hasPermission('Edit', self._client.userid,
+ self._classname) or self._nodeid == self._client.userid
+
+ def is_view_ok(self):
+ ''' Is the user allowed to View the current class?
+ Also check whether this is the current user's info.
+ '''
+ return self._db.security.hasPermission('Edit', self._client.userid,
+ self._classname) or self._nodeid == self._client.userid
+
class HTMLProperty:
''' String, Number, Date, Interval HTMLProperty
return _('*encrypted*')
def field(self, size = 30):
- ''' Render a form edit field for the property
+ ''' Render a form edit field for the property.
'''
return '<input type="password" name="%s" size="%s">'%(self._name, size)
+ def confirm(self, size = 30):
+ ''' Render a second form edit field for the property, used for
+ confirmation that the user typed the password correctly. Generates
+ a field with name "name:confirm".
+ '''
+ return '<input type="password" name="%s:confirm" size="%s">'%(
+ self._name, size)
+
class NumberHTMLProperty(HTMLProperty):
def plain(self):
''' Render a "plain" representation of the property
value = cgi.escape(value)
return value
- def field(self):
+ def field(self, showid=0, size=None):
''' Render a form edit field for the property
'''
linkcl = self._db.getclass(self._prop.classname)
sort_on = 'order'
else:
sort_on = linkcl.labelprop()
- options = linkcl.filter(None, {}, [sort_on], [])
+ options = linkcl.filter(None, {}, ('+', sort_on), (None, None))
# TODO: make this a field display, not a menu one!
- l = ['<select name="%s">'%property]
+ l = ['<select name="%s">'%self._name]
k = linkcl.labelprop(1)
- if value is None:
+ if self._value is None:
s = 'selected '
else:
s = ''
l.append(_('<option %svalue="-1">- no selection -</option>')%s)
for optionid in options:
- option = linkcl.get(optionid, k)
+ # get the option value, and if it's None use an empty string
+ option = linkcl.get(optionid, k) or ''
+
+ # figure if this option is selected
s = ''
- if optionid == value:
+ if optionid == self._value:
s = 'selected '
+
+ # figure the label
if showid:
lab = '%s%s: %s'%(self._prop.classname, optionid, option)
else:
lab = option
+
+ # truncate if it's too long
if size is not None and len(lab) > size:
lab = lab[:size-3] + '...'
+
+ # and generate
lab = cgi.escape(lab)
l.append('<option %svalue="%s">%s</option>'%(s, optionid, lab))
l.append('</select>')
# sort function
sortfunc = make_sort_function(self._db, self._prop.classname)
- # force the value to be a single choice
- if isinstance(value, type('')):
- value = value[0]
linkcl = self._db.getclass(self._prop.classname)
l = ['<select name="%s">'%self._name]
k = linkcl.labelprop(1)
sort_on = ('+', linkcl.labelprop())
options = linkcl.filter(None, conditions, sort_on, (None, None))
for optionid in options:
- option = linkcl.get(optionid, k)
+ # get the option value, and if it's None use an empty string
+ option = linkcl.get(optionid, k) or ''
+
+ # figure if this option is selected
s = ''
if value in [optionid, option]:
s = 'selected '
+
+ # figure the label
if showid:
lab = '%s%s: %s'%(self._prop.classname, optionid, option)
else:
lab = option
+
+ # truncate if it's too long
if size is not None and len(lab) > size:
lab = lab[:size-3] + '...'
if additional:
for propname in additional:
m.append(linkcl.get(optionid, propname))
lab = lab + ' (%s)'%', '.join(map(str, m))
+
+ # and generate
lab = cgi.escape(lab)
l.append('<option %svalue="%s">%s</option>'%(s, optionid, lab))
l.append('</select>')
if value:
value.sort(sortfunc)
# map the id to the label property
+ if not linkcl.getkey():
+ showid=1
if not showid:
k = linkcl.labelprop(1)
value = [linkcl.get(v, k) for v in value]
l = ['<select multiple name="%s" size="%s">'%(self._name, height)]
k = linkcl.labelprop(1)
for optionid in options:
- option = linkcl.get(optionid, k)
+ # get the option value, and if it's None use an empty string
+ option = linkcl.get(optionid, k) or ''
+
+ # figure if this option is selected
s = ''
if optionid in value or option in value:
s = 'selected '
+
+ # figure the label
if showid:
lab = '%s%s: %s'%(self._prop.classname, optionid, option)
else:
lab = option
+ # truncate if it's too long
if size is not None and len(lab) > size:
lab = lab[:size-3] + '...'
if additional:
for propname in additional:
m.append(linkcl.get(optionid, propname))
lab = lab + ' (%s)'%', '.join(m)
+
+ # and generate
lab = cgi.escape(lab)
l.append('<option %svalue="%s">%s</option>'%(s, optionid,
lab))
"form" the CGI form as a cgi.FieldStorage
"env" the CGI environment variables
- "url" the current URL path for this request
"base" the base URL for this instance
"user" a HTMLUser instance for this user
"classname" the current classname (possibly None)
self.form = client.form
self.env = client.env
self.base = client.base
- self.url = client.url
self.user = HTMLUser(client, 'user', client.userid)
# store the current class name and action
d['env'] = e
return '''
form: %(form)s
-url: %(url)r
base: %(base)r
classname: %(classname)r
template: %(template)r