Commit 41079120 authored by Evan Simpson's avatar Evan Simpson

Add "prefix" attribute to dtml-in and dtml-tree tags.

parent bdab8faf
......@@ -402,13 +402,13 @@
''' #'
__rcs_id__='$Id: DT_In.py,v 1.50 2001/04/27 20:27:39 shane Exp $'
__version__='$Revision: 1.50 $'[11:-2]
__rcs_id__='$Id: DT_In.py,v 1.51 2001/05/16 19:07:02 evan Exp $'
__version__='$Revision: 1.51 $'[11:-2]
import sys
from DT_Util import ParseError, parse_params, name_param, str
from DT_Util import render_blocks, InstanceDict, ValidationError, Eval
from string import find, atoi, join, split, lower
from DT_Util import simple_name, add_with_prefix
import re
from DT_InSV import sequence_variables, opt
TupleType=type(())
......@@ -437,7 +437,8 @@ class InClass:
orphan='3',overlap='1',mapping=1,
skip_unauthorized=1,
previous=1, next=1, expr='', sort='',
reverse=1, sort_expr='', reverse_expr='')
reverse=1, sort_expr='', reverse_expr='',
prefix='')
self.args=args
has_key=args.has_key
......@@ -458,6 +459,11 @@ class InClass:
for n in 'start', 'size', 'end':
if has_key(n): self.batch=1
prefix = args.get('prefix')
if prefix and not simple_name(prefix):
raise ParseError, _tm(
'prefix is not a simple name', 'in')
for n in 'orphan','overlap','previous','next':
if has_key(n) and not self.batch:
raise ParseError, (
......@@ -470,12 +476,12 @@ class InClass:
if has_key('start'):
v=args['start']
if type(v)==type(''):
try: atoi(v)
try: int(v)
except:
self.start_name_re=re.compile(
'&+'+
join(map(lambda c: "[%s]" % c, v),'')+
''.join(["[%s]" % c for c in v])+
'=[0-9]+&+')
name,expr=name_param(args,'in',1)
......@@ -546,17 +552,22 @@ class InClass:
try: query_string=md['QUERY_STRING']
except: query_string=''
vars=sequence_variables(sequence,'?'+query_string,self.start_name_re)
prefix = params.get('prefix')
vars = sequence_variables(sequence, '?'+query_string,
self.start_name_re, prefix)
kw=vars.data
pkw = add_with_prefix(kw, 'sequence', prefix)
for k, v in kw.items():
pkw[k] = v
pkw['sequence-step-size']=sz
pkw['sequence-step-overlap']=overlap
pkw['sequence-step-start']=start
pkw['sequence-step-end']=end
pkw['sequence-step-start-index']=start-1
pkw['sequence-step-end-index']=end-1
pkw['sequence-step-orphan']=orphan
kw['mapping']=mapping
kw['sequence-step-size']=sz
kw['sequence-step-overlap']=overlap
kw['sequence-step-start']=start
kw['sequence-step-end']=end
kw['sequence-step-start-index']=start-1
kw['sequence-step-end-index']=end-1
kw['sequence-step-orphan']=orphan
push=md._push
pop=md._pop
......@@ -569,10 +580,10 @@ class InClass:
if first > 0:
pstart,pend,psize=opt(0,first+overlap,
sz,orphan,sequence)
kw['previous-sequence']=1
kw['previous-sequence-start-index']=pstart-1
kw['previous-sequence-end-index']=pend-1
kw['previous-sequence-size']=pend+1-pstart
pkw['previous-sequence']=1
pkw['previous-sequence-start-index']=pstart-1
pkw['previous-sequence-end-index']=pend-1
pkw['previous-sequence-size']=pend+1-pstart
result=render(section,md)
elif self.elses: result=render(self.elses, md)
......@@ -589,10 +600,10 @@ class InClass:
else:
pstart,pend,psize=opt(end+1-overlap,0,
sz,orphan,sequence)
kw['next-sequence']=1
kw['next-sequence-start-index']=pstart-1
kw['next-sequence-end-index']=pend-1
kw['next-sequence-size']=pend+1-pstart
pkw['next-sequence']=1
pkw['next-sequence-start-index']=pstart-1
pkw['next-sequence-end-index']=pend-1
pkw['next-sequence-size']=pend+1-pstart
result=render(section,md)
else:
result = []
......@@ -600,18 +611,18 @@ class InClass:
read_guard = md.read_guard
for index in range(first,end):
# preset
kw['previous-sequence']= 0
kw['next-sequence']= 0 # now more often defined then previously
pkw['previous-sequence']= 0
pkw['next-sequence']= 0 # now more often defined then previously
#
if index==first or index==last:
# provide batching information
if first > 0:
pstart,pend,psize=opt(0,first+overlap,
sz,orphan,sequence)
if index==first: kw['previous-sequence']=1
kw['previous-sequence-start-index']=pstart-1
kw['previous-sequence-end-index']=pend-1
kw['previous-sequence-size']=pend+1-pstart
if index==first: pkw['previous-sequence']=1
pkw['previous-sequence-start-index']=pstart-1
pkw['previous-sequence-end-index']=pend-1
pkw['previous-sequence-size']=pend+1-pstart
try:
# The following line is a sneaky way to
# test whether there are more items,
......@@ -619,20 +630,20 @@ class InClass:
sequence[end]
pstart,pend,psize=opt(end+1-overlap,0,
sz,orphan,sequence)
if index==last: kw['next-sequence']=1
kw['next-sequence-start-index']=pstart-1
kw['next-sequence-end-index']=pend-1
kw['next-sequence-size']=pend+1-pstart
if index==last: pkw['next-sequence']=1
pkw['next-sequence-start-index']=pstart-1
pkw['next-sequence-end-index']=pend-1
pkw['next-sequence-size']=pend+1-pstart
except: pass
if index==last: kw['sequence-end']=1
if index==last: pkw['sequence-end']=1
if read_guard is not None:
try: client = read_guard(sequence)[index]
except ValidationError, vv:
if (params.has_key('skip_unauthorized') and
params['skip_unauthorized']):
if index==first: kw['sequence-start']=0
if index==first: pkw['sequence-start']=0
continue
tb = sys.exc_info()[2]
raise ValidationError, '(item %s): %s' % (
......@@ -640,7 +651,7 @@ class InClass:
else:
client = sequence[index]
kw['sequence-index']=index
pkw['sequence-index']=index
if type(client)==TupleType and len(client)==2:
client=client[1]
......@@ -650,10 +661,10 @@ class InClass:
try: append(render(section, md))
finally: pop(1)
if index==first: kw['sequence-start']=0
if index==first: pkw['sequence-start']=0
result=join(result, '')
result = ''.join(result)
finally:
tb = None
......@@ -696,8 +707,12 @@ class InClass:
elif self.reverse is not None:
sequence=self.reverse_sequence(sequence)
vars=sequence_variables(sequence)
prefix = self.args.get('prefix')
vars=sequence_variables(sequence, alt_prefix=prefix)
kw=vars.data
pkw = add_with_prefix(kw, 'sequence', prefix)
for k, v in kw.items():
pkw[k] = v
kw['mapping']=mapping
l=len(sequence)
......@@ -714,13 +729,13 @@ class InClass:
append=result.append
read_guard = md.read_guard
for index in range(l):
if index==last: kw['sequence-end']=1
if index==last: pkw['sequence-end']=1
if read_guard is not None:
try: client = read_guard(sequence)[index]
except ValidationError, vv:
if (self.args.has_key('skip_unauthorized') and
self.args['skip_unauthorized']):
if index==1: kw['sequence-start']=0
if index==1: pkw['sequence-start']=0
continue
tb = sys.exc_info()[2]
raise ValidationError, '(item %s): %s' % (
......@@ -728,7 +743,7 @@ class InClass:
else:
client = sequence[index]
kw['sequence-index']=index
pkw['sequence-index']=index
if type(client)==TupleType and len(client)==2:
client=client[1]
......@@ -737,9 +752,9 @@ class InClass:
try: append(render(section, md))
finally: pop()
if index==0: kw['sequence-start']=0
if index==0: pkw['sequence-start']=0
result=join(result, '')
result = ''.join(result)
finally:
tb = None
......@@ -759,9 +774,9 @@ class InClass:
# eg <dtml-in "foo" sort="akey/nocase,anotherkey/cmp/desc">
sort=self.sort
need_sortfunc = find(sort, '/') >= 0
need_sortfunc = sort.find('/') >= 0
sortfields = split(sort, ',') # multi sort = key1,key2
sortfields = sort.split(',') # multi sort = key1,key2
multsort = len(sortfields) > 1 # flag: is multiple sort
if need_sortfunc:
......@@ -834,23 +849,23 @@ def int_param(params,md,name,default=0, st=type('')):
try: v=params[name]
except: v=default
if v:
try: v=atoi(v)
try: v=int(v)
except:
v=md[v]
if type(v) is st: v=atoi(v)
if type(v) is st: v=int(v)
return v
# phd: Advanced sort support
def nocase(str1, str2):
return cmp(lower(str1), lower(str2))
return cmp(str1.lower(), str2.lower())
if sys.modules.has_key("locale"): # only if locale is already imported
from locale import strcoll
def strcoll_nocase(str1, str2):
return strcoll(lower(str1), lower(str2))
return strcoll(str1.lower(), str2.lower())
def make_sortfunctions(sortfields, md):
......@@ -859,7 +874,7 @@ def make_sortfunctions(sortfields, md):
sf_list = []
for field in sortfields:
f = split(field, '/')
f = field.split('/')
l = len(f)
if l == 1:
......@@ -886,7 +901,7 @@ def make_sortfunctions(sortfields, md):
else: # no - look it up in the namespace
func = md.getitem(f_name, 0)
sort_order = lower(f[2])
sort_order = f[2].lower()
if sort_order == "asc":
multiplier = +1
......
......@@ -85,10 +85,9 @@
__doc__='''Sequence variables support
$Id: DT_InSV.py,v 1.19 2001/04/27 18:07:10 andreas Exp $'''
__version__='$Revision: 1.19 $'[11:-2]
$Id: DT_InSV.py,v 1.20 2001/05/16 19:07:02 evan Exp $'''
__version__='$Revision: 1.20 $'[11:-2]
from string import lower, rfind, split, join
from math import sqrt
import re
TupleType=type(())
......@@ -100,11 +99,16 @@ except: mv=None
class sequence_variables:
def __init__(self,items=None,query_string='',start_name_re=None):
alt_prefix = None
def __init__(self,items=None,query_string='',start_name_re=None,
alt_prefix=''):
self.items=items
self.query_string=query_string
self.start_name_re=start_name_re
if alt_prefix:
self.alt_prefix = alt_prefix + '_'
self.data=data={
'previous-sequence': 0,
......@@ -126,7 +130,7 @@ class sequence_variables:
if type(i) is tt and len(i)==2: return i[1]
return i
def roman(self,index): return lower(self.Roman(index))
def roman(self,index): return self.Roman(index).lower()
def Roman(self,num):
# Force number to be an integer value
......@@ -165,12 +169,12 @@ class sequence_variables:
# Replaces special cases in Roman Numerals
roman = sub('DCCCC', 'CM', roman)
roman = sub('CCCC', 'CD', roman)
roman = sub('LXXXX', 'XC', roman)
roman = sub('XXXX', 'XL', roman)
roman = sub('VIIII', 'IX', roman)
roman = sub('IIII', 'IV', roman)
roman = roman.replace('DCCCC', 'CM')
roman = roman.replace('CCCC', 'CD')
roman = roman.replace('LXXXX', 'XC')
roman = roman.replace('XXXX', 'XL')
roman = roman.replace('VIIII', 'IX')
roman = roman.replace('IIII', 'IV')
return roman
......@@ -196,7 +200,7 @@ class sequence_variables:
return self.value(index,name) != self.value(index+1,name)
def length(self, ignored):
l=self.data['sequence-length']=len(self.items)
l=self['sequence-length']=len(self.items)
return l
def query(self, *ignored):
......@@ -227,7 +231,7 @@ class sequence_variables:
query_string='?'+query_string[1:]
else: query_string='?'
self.data['sequence-query']=query_string
self['sequence-query']=query_string
return query_string
......@@ -249,7 +253,11 @@ class sequence_variables:
for item in items:
try:
if mapping: item=item[name]
else: item=getattr(item,name)
else:
try: item=getattr(item,name)
except:
if name != 'item':
raise
try:
if item is mv:
item = None
......@@ -389,6 +397,12 @@ class sequence_variables:
}
for n in statistic_names: special_prefixes[n]=statistics
def __setitem__(self, key, value):
self.data[key] = value
if self.alt_prefix:
if key.startswith('sequence-'): key = key[9:]
self.data[self.alt_prefix + key] = value
def __getitem__(self,key,
special_prefixes=special_prefixes,
special_prefix=special_prefixes.has_key
......@@ -396,11 +410,21 @@ class sequence_variables:
data=self.data
if data.has_key(key): return data[key]
l=rfind(key,'-')
if l < 0: raise KeyError, key
suffix=key[l+1:]
prefix=key[:l]
l=key.rfind('-')
if l < 0:
alt_prefix = self.alt_prefix
if not (alt_prefix and key.startswith(alt_prefix)):
raise KeyError, key
suffix = key[len(alt_prefix):].replace('_', '-')
if '-' in suffix:
try: return self[suffix]
except KeyError: pass
prefix = 'sequence'
key = 'sequence-' + suffix
else:
suffix=key[l+1:]
prefix=key[:l]
if hasattr(self, suffix):
try: v=data[prefix+'-index']
......@@ -420,11 +444,6 @@ class sequence_variables:
raise KeyError, key
def sub(s1, s2, src):
return join(split(src, s1), s2)
def opt(start,end,size,orphan,sequence):
if size < 1:
if start > 0 and end > 0 and end >= start:
......
......@@ -82,11 +82,10 @@
# attributions are listed in the accompanying credits file.
#
##############################################################################
'''$Id: DT_Util.py,v 1.76 2001/04/30 14:46:00 shane Exp $'''
__version__='$Revision: 1.76 $'[11:-2]
'''$Id: DT_Util.py,v 1.77 2001/05/16 19:07:02 evan Exp $'''
__version__='$Revision: 1.77 $'[11:-2]
import re, os
from string import lower
from RestrictedPython.Guards import safe_builtins
from RestrictedPython.Utilities import utility_builtins
from RestrictedPython.Eval import RestrictionCapableEval
......@@ -223,6 +222,25 @@ class Eval(RestrictionCapableEval):
md._push(kw)
return self.eval(md)
simple_name = re.compile('[a-z][a-z0-9_]*', re.I).match
class Add_with_prefix:
def __init__(self, map, defprefix, prefix):
self.map = map
self.defprefix = defprefix
self.prefix = prefix
def __setitem__(self, name, value):
map = self.map
map[name] = value
dp = self.defprefix
if name.startswith(dp + '-'):
map[self.prefix + name[len(dp):].replace('-', '_')] = value
else:
map['%s_%s' % (self.prefix, name)] = value
def add_with_prefix(map, defprefix, prefix):
if not prefix: return map
return Add_with_prefix(map, defprefix, prefix)
def name_param(params,tag='',expr=0, attr='name', default_unnamed=1):
used=params.has_key
......@@ -377,11 +395,11 @@ def parse_params(text,
mo_unq = qunparmre.match(text)
if mo_p:
name=lower(mo_p.group(2))
name=mo_p.group(2).lower()
value=mo_p.group(3)
l=len(mo_p.group(1))
elif mo_q:
name=lower(mo_q.group(2))
name=mo_q.group(2).lower()
value=mo_q.group(3)
l=len(mo_q.group(1))
elif mo_unp:
......
......@@ -50,6 +50,11 @@ in: Loops over sequences
next -- Iterates once if there is a next batch. Sets batch variables
for the next sequence.
prefix=string -- Provide versions of the tag variables that start
with this prefix instead of "sequence", and that use underscores
(_) instead of hyphens (-). The prefix must start with a letter and
contain only alphanumeric characters and underscores (_).
Tag Variables
Current Item Variables
......@@ -203,6 +208,19 @@ in: Loops over sequences
title: <dtml-var title><br>
</dtml-in>
Looping over two sets of objects, using prefixes::
<dtml-let rows="(1,2,3)" cols="(4,5,6)">
<dtml-in rows prefix="row">
<dtml-in cols prefix="col">
<dtml-var expr="row_item * col_item"><br>
<dtml-if col_end>
<dtml-var expr="col_total_item * row_mean_item">
</dtml-if>
</dtml-in>
</dtml-in>
</dtml-let>
Looping over a list of '(key, value)' tuples::
<dtml-in objectItems>
......
......@@ -70,6 +70,11 @@ tree: Inserts a tree widget
expanding and contracting widget links. This attribute is for
advanced usage only.
prefix=string -- Provide versions of the tag variables that start
with this prefix instead of "tree", and that use underscores
(_) instead of hyphens (-). The prefix must start with a letter and
contain only alphanumeric characters and underscores (_).
Tag Variables
tree-item-expanded -- True if the current node is expanded.
......
......@@ -84,16 +84,17 @@
##############################################################################
"""Rendering object hierarchies as Trees
"""
__rcs_id__='$Id: TreeTag.py,v 1.46 2001/04/27 20:27:57 shane Exp $'
__version__='$Revision: 1.46 $'[11:-2]
__rcs_id__='$Id: TreeTag.py,v 1.47 2001/05/16 19:07:06 evan Exp $'
__version__='$Revision: 1.47 $'[11:-2]
from DocumentTemplate.DT_Util import *
from DocumentTemplate.DT_String import String
from string import join, split, rfind, find, translate
from string import join, split, rfind, find, translate, replace
from urllib import quote, unquote
from zlib import compress, decompress
from binascii import b2a_base64, a2b_base64
import re
tbl=join(map(chr, range(256)),'')
tplus=tbl[:ord('+')]+'-'+tbl[ord('+')+1:]
......@@ -116,7 +117,7 @@ class Tree:
# closed_decoration=None,
# childless_decoration=None,
assume_children=1,
urlparam=None)
urlparam=None, prefix=None)
has_key=args.has_key
if has_key('') or has_key('name') or has_key('expr'):
......@@ -137,6 +138,11 @@ class Tree:
if not has_key('url'): args['url']='tpURL'
if not has_key('childless_decoration'):
args['childless_decoration']=''
prefix = args.get('prefix')
if prefix and not simple_name(prefix):
raise ParseError, _tm(
'prefix is not a simple name', 'tree')
self.__name__ = name
self.section=section.blocks
......@@ -251,6 +257,11 @@ def tpRender(self, md, section, args,
treeData={'tree-root-url': root,
'tree-colspan': colspan,
'tree-state': state }
prefix = args.get('prefix')
if prefix:
for k, v in treeData.items():
treeData[prefix + replace(k[4:], '-', '_')] = v
md._push(InstanceDict(self, md))
md._push(treeData)
......@@ -283,9 +294,10 @@ def tpRenderTABLE(self, id, root_url, url, state, substate, diff, data,
url = (url and ('%s/%s' % (url, tpUrl))) or tpUrl
root_url = root_url or tpUrl
treeData['tree-item-url']=url
treeData['tree-level']=level
treeData['tree-item-expanded']=0
ptreeData = add_with_prefix(treeData, 'tree', args.get('prefix'))
ptreeData['tree-item-url']=url
ptreeData['tree-level']=level
ptreeData['tree-item-expanded']=0
idattr=args['id']
output=data.append
......@@ -404,7 +416,7 @@ def tpRenderTABLE(self, id, root_url, url, state, substate, diff, data,
param = ""
if exp:
treeData['tree-item-expanded']=1
ptreeData['tree-item-expanded']=1
output('<A NAME="%s" HREF="%s?%stree-c=%s#%s">'
'<IMG SRC="%s/p_/mi" ALT="-" BORDER=0></A>' %
(id, root_url, param, s, id, script))
......@@ -463,7 +475,7 @@ def tpRenderTABLE(self, id, root_url, url, state, substate, diff, data,
else: doc=None
if doc is not None:
treeData['-tree-substate-']=sub
treeData['tree-level']=level
ptreeData['tree-level']=level
md._push(treeData)
try: output(doc(
None,md,
......@@ -482,7 +494,7 @@ def tpRenderTABLE(self, id, root_url, url, state, substate, diff, data,
else: doc=None
if doc is not None:
treeData['-tree-substate-']=sub
treeData['tree-level']=level
ptreeData['tree-level']=level
md._push(treeData)
try: output(doc(
None,md,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment