Commit ca3753b2 authored by Hanno Schlichting's avatar Hanno Schlichting

Moved DocumentTemplate and TreeDisplay to their own distro

parent 13bc9b23
......@@ -39,6 +39,7 @@ eggs =
AccessControl
Acquisition
DateTime
DocumentTemplate
ExtensionClass
Missing
MultiMapping
......
......@@ -31,13 +31,6 @@ setup(name='Zope2',
package_dir={'': 'src'},
ext_modules=[
# DocumentTemplate
Extension(
name='DocumentTemplate.cDocumentTemplate',
include_dirs=['include', 'src'],
sources=['src/DocumentTemplate/cDocumentTemplate.c'],
depends=['include/ExtensionClass/ExtensionClass.h']),
# indexes
Extension(
name='Products.ZCTextIndex.stopper',
......@@ -52,6 +45,7 @@ setup(name='Zope2',
'AccessControl',
'Acquisition',
'DateTime',
'DocumentTemplate',
'ExtensionClass',
'Missing',
'MultiMapping',
......
This diff is collapsed.
##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# 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
#
##############################################################################
__doc__='''Conditional insertion
Conditional insertion is performed using 'if' and 'else'
commands.
To include text when an object is true using the EPFS
format, use::
%(if name)[
text
%(if name)]
To include text when an object is true using the HTML
format, use::
<!--#if name-->
text
<!--#/if name-->
where 'name' is the name bound to the object.
To include text when an object is false using the EPFS
format, use::
%(else name)[
text
%(else name)]
To include text when an object is false using the HTML
format, use::
<!--#else name-->
text
<!--#/else name-->
Finally to include text when an object is true and to
include different text when the object is false using the
EPFS format, use::
%(if name)[
true text
%(if name)]
%(else name)[
false text
%(else name)]
and to include text when an object is true and to
include different text when the object is false using the
HTML format, use::
<!--#if name-->
true text
<!--#else name-->
false text
<!--#/if name-->
Notes:
- if a variable is nor defined, it is considered to be false.
- A variable if only evaluated once in an 'if' tag. If the value
is used inside the tag, including in enclosed tags, the
variable is not reevaluated.
'''
__rcs_id__='$Id$'
__version__='$Revision: 1.19 $'[11:-2]
from DocumentTemplate.DT_Util import ParseError, parse_params, name_param, str
class If:
blockContinuations='else','elif'
name='if'
elses=None
expr=''
def __init__(self, blocks):
tname, args, section = blocks[0]
args=parse_params(args, name='', expr='')
name,expr=name_param(args,'if',1)
self.__name__= name
if expr is None: cond=name
else: cond=expr.eval
sections=[cond, section.blocks]
if blocks[-1][0]=='else':
tname, args, section = blocks[-1]
del blocks[-1]
args=parse_params(args, name='')
if args:
ename,expr=name_param(args,'else',1)
if ename != name:
raise ParseError, ('name in else does not match if', 'in')
elses=section.blocks
else: elses=None
for tname, args, section in blocks[1:]:
if tname=='else':
raise ParseError, (
'more than one else tag for a single if tag', 'in')
args=parse_params(args, name='', expr='')
name,expr=name_param(args,'elif',1)
if expr is None: cond=name
else: cond=expr.eval
sections.append(cond)
sections.append(section.blocks)
if elses is not None: sections.append(elses)
self.simple_form=('i',)+tuple(sections)
class Unless:
name='unless'
blockContinuations=()
def __init__(self, blocks):
tname, args, section = blocks[0]
args=parse_params(args, name='', expr='')
name,expr=name_param(args,'unless',1)
if expr is None: cond=name
else: cond=expr.eval
self.simple_form=('i',cond,None,section.blocks)
class Else(Unless):
# The else tag is included for backward compatibility and is deprecated.
name='else'
This diff is collapsed.
This diff is collapsed.
##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# 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
#
##############################################################################
''' The Let tag was contributed to Zope by and is copyright, 1999
Phillip J. Eby. Permission has been granted to release the Let tag
under the Zope Public License.
Let name=value...
The 'let' tag is used to bind variables to values within a block.
The text enclosed in the let tag is rendered using information
from the given variables or expressions.
For example::
<!--#let foofunc="foo()" my_bar=bar-->
foo() = <!--#var foofunc-->,
bar = <!--#var my_bar-->
<!--#/let-->
Notice that both 'name' and 'expr' style attributes may be used to
specify data. 'name' style attributes (e.g. my_bar=bar) will be
rendered as they are for var/with/in/etc. Quoted attributes will
be treated as Python expressions.
Variables are processed in sequence, so later assignments can
reference and/or overwrite the results of previous assignments,
as desired.
'''
import re
from DocumentTemplate.DT_Util import render_blocks, Eval, ParseError
from DocumentTemplate.DT_Util import str # Probably needed due to
# hysterical pickles.
class Let:
blockContinuations=()
name='let'
def __init__(self, blocks):
tname, args, section = blocks[0]
self.__name__ = args
self.section = section.blocks
self.args = args = parse_let_params(args)
for i in range(len(args)):
name,expr = args[i]
if expr[:1]=='"' and expr[-1:]=='"' and len(expr) > 1:
# expr shorthand
expr=expr[1:-1]
try: args[i] = name, Eval(expr).eval
except SyntaxError, v:
m,(huh,l,c,src) = v
raise ParseError, (
'<strong>Expression (Python) Syntax error</strong>:'
'\n<pre>\n%s\n</pre>\n' % v[0],
'let')
def render(self, md):
d={}; md._push(d)
try:
for name,expr in self.args:
if type(expr) is type(''): d[name]=md[expr]
else: d[name]=expr(md)
return render_blocks(self.section, md)
finally: md._pop(1)
__call__ = render
def parse_let_params(text,
result=None,
tag='let',
parmre=re.compile('([\000- ]*([^\000- ="]+)=([^\000- ="]+))'),
qparmre=re.compile('([\000- ]*([^\000- ="]+)="([^"]*)")'),
**parms):
result=result or []
mo = parmre.match(text)
mo1= qparmre.match(text)
if mo is not None:
name=mo.group(2)
value=mo.group(3)
l=len(mo.group(1))
elif mo1 is not None:
name=mo1.group(2)
value='"%s"' % mo1.group(3)
l=len(mo1.group(1))
else:
if not text or not text.strip(): return result
raise ParseError, ('invalid parameter: "%s"' % text, tag)
result.append((name,value))
text=text[l:].strip()
if text: return parse_let_params(text,result,tag,**parms)
else: return result
##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# 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
#
##############################################################################
'''Raising exceptions
Errors can be raised from DTML using the 'raise' tag.
For example::
<!--#if expr="condition_that_tests_input"-->
<!--#raise type="Input Error"-->
The value you entered is not valid
<!--#/raise-->
<!--#/if-->
'''
__rcs_id__='$Id$'
__version__='$Revision: 1.13 $'[11:-2]
from zExceptions import upgradeException
from zExceptions import convertExceptionType
from DocumentTemplate.DT_Util import name_param
from DocumentTemplate.DT_Util import parse_params
from DocumentTemplate.DT_Util import render_blocks
class InvalidErrorTypeExpression(Exception):
pass
class Raise:
blockContinuations=()
name='raise'
expr=''
def __init__(self, blocks):
tname, args, section = blocks[0]
self.section = section.blocks
args = parse_params(args, type='', expr='')
self.__name__, self.expr = name_param(args, 'raise', 1, attr='type')
def render(self,md):
expr = self.expr
if expr is None:
t = convertExceptionType(self.__name__)
if t is None:
t = RuntimeError
else:
try:
t = expr.eval(md)
except:
t = convertExceptionType(self.__name__)
if t is None:
t = InvalidErrorTypeExpression
try:
v = render_blocks(self.section, md)
except:
v = 'Invalid Error Value'
# String Exceptions are deprecated on Python 2.5 and
# plain won't work at all on Python 2.6. So try to upgrade it
# to a real exception.
t, v = upgradeException(t, v)
raise t, v
__call__ = render
##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# 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
#
##############################################################################
__version__='$Revision: 1.9 $'[11:-2]
from DocumentTemplate.DT_Util import parse_params, name_param
class ReturnTag:
name='return'
expr=None
def __init__(self, args):
args = parse_params(args, name='', expr='')
name, expr = name_param(args, 'var', 1)
self.__name__ = name
self.expr = expr
def render(self, md):
if self.expr is None:
val = md[self.__name__]
else:
val = self.expr.eval(md)
raise DTReturn(val)
__call__ = render
class DTReturn:
def __init__(self, v):
self.v = v
This diff is collapsed.
##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# 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
#
##############################################################################
import sys, traceback
from cStringIO import StringIO
from DocumentTemplate.DT_Util import ParseError, parse_params, render_blocks
from DocumentTemplate.DT_Util import namespace, InstanceDict
from DocumentTemplate.DT_Return import DTReturn
class Try:
"""Zope DTML Exception handling
usage:
<!--#try-->
<!--#except SomeError AnotherError-->
<!--#except YetAnotherError-->
<!--#except-->
<!--#else-->
<!--#/try-->
or:
<!--#try-->
<!--#finally-->
<!--#/try-->
The DTML try tag functions quite like Python's try command.
The contents of the try tag are rendered. If an exception is raised,
then control switches to the except blocks. The first except block to
match the type of the error raised is rendered. If an except block has
no name then it matches all raised errors.
The try tag understands class-based exceptions, as well as string-based
exceptions. Note: the 'raise' tag raises string-based exceptions.
Inside the except blocks information about the error is available via
three variables.
'error_type' -- This variable is the name of the exception caught.
'error_value' -- This is the caught exception's value.
'error_tb' -- This is a traceback for the caught exception.
The optional else block is rendered when no exception occurs in the
try block. Exceptions in the else block are not handled by the preceding
except blocks.
The try..finally form specifies a `cleanup` block, to be rendered even
when an exception occurs. Note that any rendered result is discarded if
an exception occurs in either the try or finally blocks. The finally block
is only of any use if you need to clean up something that will not be
cleaned up by the transaction abort code.
The finally block will always be called, wether there was an exception in
the try block or not, or wether or not you used a return tag in the try
block. Note that any output of the finally block is discarded if you use a
return tag in the try block.
If an exception occurs in the try block, and an exception occurs in the
finally block, or you use the return tag in that block, any information
about that first exception is lost. No information about the first
exception is available in the finally block. Also, if you use a return tag
in the try block, and an exception occurs in the finally block or you use
a return tag there as well, the result returned in the try block will be
lost.
Original version by Jordan B. Baker.
Try..finally and try..else implementation by Martijn Pieters.
"""
name = 'try'
blockContinuations = 'except', 'else', 'finally'
finallyBlock=None
elseBlock=None
def __init__(self, blocks):
tname, args, section = blocks[0]
self.args = parse_params(args)
self.section = section.blocks
# Find out if this is a try..finally type
if len(blocks) == 2 and blocks[1][0] == 'finally':
self.finallyBlock = blocks[1][2].blocks
# This is a try [except]* [else] block.
else:
# store handlers as tuples (name,block)
self.handlers = []
defaultHandlerFound = 0
for tname,nargs,nsection in blocks[1:]:
if tname == 'else':
if not self.elseBlock is None:
raise ParseError, (
'No more than one else block is allowed',
self.name)
self.elseBlock = nsection.blocks
elif tname == 'finally':
raise ParseError, (
'A try..finally combination cannot contain '
'any other else, except or finally blocks',
self.name)
else:
if not self.elseBlock is None:
raise ParseError, (
'The else block should be the last block '
'in a try tag', self.name)
for errname in nargs.split():
self.handlers.append((errname,nsection.blocks))
if nargs.strip()=='':
if defaultHandlerFound:
raise ParseError, (
'Only one default exception handler '
'is allowed', self.name)
else:
defaultHandlerFound = 1
self.handlers.append(('',nsection.blocks))
def render(self, md):
if (self.finallyBlock is None):
return self.render_try_except(md)
else:
return self.render_try_finally(md)
def render_try_except(self, md):
result = ''
# first we try to render the first block
try:
result = render_blocks(self.section, md)
except DTReturn:
raise
except:
# but an error occurs.. save the info.
t,v = sys.exc_info()[:2]
if type(t)==type(''):
errname = t
else:
errname = t.__name__
handler = self.find_handler(t)
if handler is None:
# we didn't find a handler, so reraise the error
raise
# found the handler block, now render it
try:
f=StringIO()
traceback.print_exc(100,f)
error_tb=f.getvalue()
ns = namespace(md, error_type=errname, error_value=v,
error_tb=error_tb)[0]
md._push(InstanceDict(ns,md))
return render_blocks(handler, md)
finally:
md._pop(1)
else:
# No errors have occured, render the optional else block
if (self.elseBlock is None):
return result
else:
return result + render_blocks(self.elseBlock, md)
def render_try_finally(self, md):
result = ''
# first try to render the first block
try:
result = render_blocks(self.section, md)
# Then handle finally block
finally:
result = result + render_blocks(self.finallyBlock, md)
return result
def find_handler(self,exception):
"recursively search for a handler for a given exception"
if type(exception)==type(''):
for e,h in self.handlers:
if exception==e or e=='':
return h
else:
return None
for e,h in self.handlers:
if e==exception.__name__ or e=='' or self.match_base(exception,e):
return h
return None
def match_base(self,exception,name):
for base in exception.__bases__:
if base.__name__==name or self.match_base(base,name):
return 1
return None
__call__ = render
##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# 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
#
##############################################################################
__doc__='''Machinery to support through-the-web editing
$Id$'''
__version__='$Revision: 1.15 $'[11:-2]
from DocumentTemplate.DT_HTML import HTML
FactoryDefaultString="Factory Default"
HTML.document_template_edit_header='<h2>Edit Document</h2>'
HTML.document_template_form_header=''
HTML.document_template_edit_footer=(
"""<FONT SIZE="-1">
<I><A HREF="http://www.zope.com">
&copy; 2002 Zope Corporation</A></I></FONT>""")
HTML._manage_editForm = HTML(
"""<HTML>
<HEAD>
<TITLE>HTML Template Editor</TITLE>
</HEAD>
<BODY bgcolor="#FFFFFF">
<!--#var document_template_edit_header-->
<FORM name="editform" ACTION="&dtml-URL1;/manage_edit" METHOD="POST">
<!--#var document_template_form_header-->
Document template source:
<center>
<br>
<dtml-let cols="REQUEST.get('dtpref_cols', '100%')"
rows="REQUEST.get('dtpref_rows', '20')">
<dtml-if expr="cols[-1]=='%'">
<textarea name="data:text" style="width: &dtml-cols;;"
<dtml-else>
<textarea name="data:text" cols="&dtml-cols;"
</dtml-if>
rows="&dtml-rows;"><dtml-var __str__></textarea>
</dtml-let>
<br>
<INPUT NAME=SUBMIT TYPE="SUBMIT" VALUE="Change">
<INPUT NAME=SUBMIT TYPE="RESET" VALUE="Reset">
<INPUT NAME="dt_edit_name" TYPE="HIDDEN"
VALUE="&dtml-URL1;">
<!--#if FactoryDefaultString-->
<INPUT NAME=SUBMIT TYPE="SUBMIT"
VALUE="&dtml-FactoryDefaultString;">
<!--#/if FactoryDefaultString-->
<INPUT NAME=SUBMIT TYPE="SUBMIT" VALUE="Cancel">
<!--#if HTTP_REFERER-->
<INPUT NAME="CANCEL_ACTION" TYPE="HIDDEN"
VALUE="&dtml-HTTP_REFERER;">
<!--#else HTTP_REFERER-->
<!--#if URL1-->
<INPUT NAME="CANCEL_ACTION" TYPE="HIDDEN"
VALUE="&dtml-URL1;">
<!--#/if URL1-->
<!--#/if HTTP_REFERER-->
</center>
</FORM>
<BR CLEAR="ALL">
<!--#var document_template_edit_footer-->
</BODY>
</HTML>""",)
HTML.editConfirmation=HTML(
"""<html><head><title>Change Successful</title></head><body>
<!--#if CANCEL_ACTION-->
<form action="&dtml-CANCEL_ACTION;" method="POST">
<center>
<em>&dtml-dt_edit_name;</em><br>has been changed.<br><br>
<input type=submit name="SUBMIT" value="OK">
</center>
</form></body></html>
<!--#else CANCEL_ACTION-->
<center>
<em>&dtml-dt_edit_name;</em><br>has been changed.
</center>
<!--#/if CANCEL_ACTION-->""")
This diff is collapsed.
This diff is collapsed.
##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# 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
#
##############################################################################
'''Nested namespace access
The 'with' tag is used to introduce nested namespaces.
The text enclosed in the with tag is rendered using information
from the given variable or expression.
For example, if the variable 'person' is bound to an object that
has attributes 'name' and 'age', then a 'with' tag like the
following can be used to access these attributes::
<!--#with person-->
<!--#var name-->,
<!--#var age-->
<!--#/with-->
Eather a 'name' or an 'expr' attribute may be used to specify data.
A 'mapping' attribute may be used to indicate that the given data
should be treated as mapping object, rather than as an object with
named attributes.
'''
__rcs_id__='$Id$'
__version__='$Revision: 1.15 $'[11:-2]
from DocumentTemplate.DT_Util import parse_params, name_param
from DocumentTemplate.DT_Util import InstanceDict, render_blocks, str
from DocumentTemplate.DT_Util import TemplateDict
class With:
blockContinuations=()
name='with'
mapping=None
only=0
def __init__(self, blocks):
tname, args, section = blocks[0]
args=parse_params(args, name='', expr='', mapping=1, only=1)
name,expr=name_param(args,'with',1)
if expr is None: expr=name
else: expr=expr.eval
self.__name__, self.expr = name, expr
self.section=section.blocks
if args.has_key('mapping') and args['mapping']: self.mapping=1
if args.has_key('only') and args['only']: self.only=1
def render(self, md):
expr=self.expr
if type(expr) is type(''): v=md[expr]
else: v=expr(md)
if not self.mapping:
if type(v) is type(()) and len(v)==1: v=v[0]
v=InstanceDict(v,md)
if self.only:
_md=md
md=TemplateDict()
if hasattr(_md, 'guarded_getattr'):
md.guarded_getattr = _md.guarded_getattr
if hasattr(_md, 'guarded_getitem'):
md.guarded_getitem = _md.guarded_getitem
md._push(v)
try: return render_blocks(self.section, md)
finally: md._pop(1)
__call__=render
##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# 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
#
##############################################################################
__doc__='''short description
$Id$'''
__version__='$Revision: 1.8 $'[11:-2]
from DocumentTemplate import *
import sys
def test1():
print HTML('area code=<!--#var expr="phone[:3]"-->')(phone='7035551212')
def test2():
print HTML('area code=<!--#var expr="phone.number"-->')(phone='7035551212')
def test3():
print HTML('area code=<!--#var expr="phone*1000"-->')(phone='7035551212')
def test4():
h=HTML(
"""
<!--#if expr="level==1"-->
level was 1
<!--#elif expr="level==2"-->
level was 2
<!--#elif expr="level==3"-->
level was 3
<!--#else-->
level was something else
<!--#endif-->
""")
for i in range(4):
print '-' * 77
print i, h(level=i)
print '-' * 77
if __name__ == "__main__":
try: command=sys.argv[1]
except: command='main'
globals()[command]()
The let tag:
is a new tag that lets you create blocks like:
<!--#in "1,2,3,4"-->
<!--#let num=sequence-item
index=sequence-index
result="num*index"-->
<!--#var num--> * <!--#var index--> = <!--#var result-->
<!--#/let-->
<!--#/in-->
Which yields:
1 * 0 = 0
2 * 1 = 2
3 * 2 = 6
4 * 3 = 12
The #let tag works like the #with tag, but is more flexible in that
it allows you to make multiple assignments, and allows you to chain
assignments, using earlier declarations in later assignments. Notice
inthe ablove example, the 'result' variable is based on 'num' and
'index', both of which are assigned in the same #let expression.
Syntacticly, each argument to be evalulated in the head of the let
tag must be seperated by a newline. Enclosing an argument in double
quotes causes it to be evaluated by the DTML expression machinery.
Un-quoted arguments are referenced by name.
Evaluation is in sequence with the result of earlier assignments
available to later ones. Later assignments can also override earlier
ones, which can be helpful for longer step-by-step calculations. The
variables thus set are in effect for the life of the <!--#let-->
block.
# alias module for backwards compatibility
from DocumentTemplate.DT_Util import Eval
def careful_mul(env, *factors):
r = 1
for factor in factors:
r=r*factor
return r
##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# 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
#
##############################################################################
'''Document templates with fill-in fields
Document templates provide for creation of textual documents, such as
HTML pages, from template source by inserting data from python objects
and name-spaces.
When a document template is created, a collection of default values to
be inserted may be specified with a mapping object and with keyword
arguments.
A document templated may be called to create a document with values
inserted. When called, an instance, a mapping object, and keyword
arguments may be specified to provide values to be inserted. If an
instance is provided, the document template will try to look up values
in the instance using getattr, so inheritence of values is supported.
If an inserted value is a function, method, or class, then an attempt
will be made to call the object to obtain values. This allows
instance methods to be included in documents.
Document templates masquerade as functions, so the python object
publisher (Bobo) will call templates that are stored as instances of
published objects. Bobo will pass the object the template was found in
and the HTTP request object.
Two source formats are supported:
Extended Python format strings (EPFS) --
This format is based on the insertion by name format strings
of python with additional format characters, '[' and ']' to
indicate block boundaries. In addition, parameters may be
used within formats to control how insertion is done.
For example:
%%(date fmt=DayOfWeek upper)s
causes the contents of variable 'date' to be inserted using
custom format 'DayOfWeek' and with all lower case letters
converted to upper case.
HTML --
This format uses HTML server-side-include syntax with
commands for inserting text. Parameters may be included to
customize the operation of a command.
For example:
<!--#var total fmt=12.2f-->
is used to insert the variable 'total' with the C format
'12.2f'.
Document templates support conditional and sequence insertion
Document templates extend python string substitition rules with a
mechanism that allows conditional insertion of template text and that
allows sequences to be inserted with element-wise insertion of
template text.
Access Control
Document templates provide a basic level of access control by
preventing access to names beginning with an underscore.
Additional control may be provided by providing document templates
with a 'guarded_getattr' and 'guarded_getitem' method. This would
typically be done by subclassing one or more of the DocumentTemplate
classes.
If provided, the the 'guarded_getattr' method will be called when
objects are accessed as instance attributes or when they are
accessed through keyed access in an expression.
Document Templates may be created 4 ways:
DocumentTemplate.String -- Creates a document templated from a
string using an extended form of python string formatting.
DocumentTemplate.File -- Creates a document templated bound to a
named file using an extended form of python string formatting.
If the object is pickled, the file name, rather than the file
contents is pickled. When the object is unpickled, then the
file will be re-read to obtain the string. Note that the file
will not be read until the document template is used the first
time.
DocumentTemplate.HTML -- Creates a document templated from a
string using HTML server-side-include rather than
python-format-string syntax.
DocumentTemplate.HTMLFile -- Creates an HTML document template
from a named file.
'''
__version__='$Revision: 1.14 $'[11:-2]
from DocumentTemplate.DT_Raise import ParseError
from DocumentTemplate.DT_String import String, File
from DocumentTemplate.DT_HTML import HTML, HTMLFile, HTMLDefault
# import DT_UI # Install HTML editing
##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# 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
#
##############################################################################
"""Package wrapper for Document Template
This wrapper allows the (now many) document template modules to be
segregated in a separate package."""
from DocumentTemplate.DT_String import String, File
from DocumentTemplate.DT_HTML import HTML, HTMLDefault, HTMLFile
# Register the dtml-tree tag
import TreeDisplay
from DocumentTemplate import security # Side effects!
del security
This diff is collapsed.
# split off into its own module for aliasing without circrefs
from cgi import escape
from DocumentTemplate.ustr import ustr
def html_quote(v, name='(Unknown name)', md={}):
return escape(ustr(v), 1)
##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# 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
#
##############################################################################
"""Python implementations of document template some features
XXX This module is no longer actively used, but is left as an
XXX implementation reference for cDocumentTemplate
$Id$"""
__version__='$Revision: 1.42 $'[11:-2]
import sys, types
from types import StringType, UnicodeType, TupleType
from DocumentTemplate.ustr import ustr
import warnings
warnings.warn('pDocumentTemplate is not longer in active use. '
'It remains only as an implementation reference.',
DeprecationWarning)
ClassTypes = [types.ClassType]
try:
from ExtensionClass import Base
except ImportError:
pass
else:
class c(Base): pass
ClassTypes.append(c.__class__)
def safe_callable(ob):
# Works with ExtensionClasses and Acquisition.
if hasattr(ob, '__class__'):
if hasattr(ob, '__call__'):
return 1
else:
return type(ob) in ClassTypes
else:
return callable(ob)
class InstanceDict:
guarded_getattr=None
def __init__(self,o,namespace,guarded_getattr=None):
self.self=o
self.cache={}
self.namespace=namespace
if guarded_getattr is None:
self.guarded_getattr = namespace.guarded_getattr
else: self.guarded_getattr = guarded_getattr
def has_key(self,key):
return hasattr(self.self,key)
def keys(self):
return self.self.__dict__.keys()
def __repr__(self): return 'InstanceDict(%s)' % str(self.self)
def __getitem__(self,key):
cache=self.cache
if cache.has_key(key): return cache[key]
inst=self.self
if key[:1]=='_':
if key != '__str__':
raise KeyError, key # Don't divuldge private data
else:
return str(inst)
get = self.guarded_getattr
if get is None:
get = getattr
try: r = get(inst, key)
except AttributeError: raise KeyError, key
self.cache[key]=r
return r
def __len__(self):
return 1
class MultiMapping:
def __init__(self): self.dicts=[]
def __getitem__(self, key):
for d in self.dicts:
try:
return d[key]
except (KeyError, AttributeError):
# XXX How do we get an AttributeError?
pass
raise KeyError, key
def push(self,d): self.dicts.insert(0,d)
def pop(self, n=1):
r = self.dicts[-1]
del self.dicts[:n]
return r
def keys(self):
kz = []
for d in self.dicts:
kz = kz + d.keys()
return kz
class DictInstance:
def __init__(self, mapping):
self.__d=mapping
def __getattr__(self, name):
try: return self.__d[name]
except KeyError: raise AttributeError, name
class TemplateDict:
level=0
def _pop(self, n=1): return self.dicts.pop(n)
def _push(self, d): return self.dicts.push(d)
def __init__(self):
m=self.dicts=MultiMapping()
self._pop=m.pop
self._push=m.push
try: self.keys=m.keys
except: pass
def __getitem__(self,key,call=1):
v = self.dicts[key]
if call:
if hasattr(v, '__render_with_namespace__'):
return v.__render_with_namespace__(self)
vbase = getattr(v, 'aq_base', v)
if safe_callable(vbase):
if getattr(vbase, 'isDocTemp', 0):
v = v(None, self)
else:
v = v()
return v
def __len__(self):
total = 0
for d in self.dicts.dicts:
total = total + len(d)
return total
def has_key(self,key):
try:
v=self.dicts[key]
except KeyError:
return 0
return 1
getitem=__getitem__
def __call__(self, *args, **kw):
if args:
if len(args)==1 and not kw:
m=args[0]
else:
m=self.__class__()
for a in args: m._push(a)
if kw: m._push(kw)
else: m=kw
return (DictInstance(m),)
def render_blocks(blocks, md):
rendered = []
append=rendered.append
for section in blocks:
if type(section) is TupleType:
l=len(section)
if l==1:
# Simple var
section=section[0]
if type(section) is StringType: section=md[section]
else: section=section(md)
section=ustr(section)
else:
# if
cache={}
md._push(cache)
try:
i=0
m=l-1
while i < m:
cond=section[i]
if type(cond) is StringType:
n=cond
try:
cond=md[cond]
cache[n]=cond
except KeyError, v:
v=str(v)
if n != v: raise KeyError, v, sys.exc_traceback
cond=None
else: cond=cond(md)
if cond:
section=section[i+1]
if section: section=render_blocks(section,md)
else: section=''
m=0
break
i=i+2
if m:
if i==m: section=render_blocks(section[i],md)
else: section=''
finally: md._pop()
elif type(section) is not StringType and type(section) is not UnicodeType:
section=section(md)
if section: rendered.append(section)
l=len(rendered)
if l==0: return ''
elif l==1: return rendered[0]
return join_unicode(rendered)
def join_unicode(rendered):
"""join a list of plain strings into a single plain string,
a list of unicode strings into a single unicode strings,
or a list containing a mix into a single unicode string with
the plain strings converted from latin-1
"""
try:
return ''.join(rendered)
except UnicodeError:
# A mix of unicode string and non-ascii plain strings.
# Fix up the list, treating normal strings as latin-1
rendered = list(rendered)
for i in range(len(rendered)):
if type(rendered[i]) is StringType:
rendered[i] = unicode(rendered[i],'latin-1')
return u''.join(rendered)
change_dtml_documents='Change DTML Documents'
change_dtml_methods='Change DTML Methods'
##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# 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
#
##############################################################################
"""Add security system support to Document Templates
"""
# Setup RestrictedDTML
from AccessControl.ImplPython import guarded_getattr
from AccessControl.ZopeGuards import guarded_getitem
RestrictedDTML = None
class BaseRestrictedDTML:
"""A mix-in for derivatives of DT_String.String that adds Zope security."""
def guarded_getattr(self, *args): # ob, name [, default]
return guarded_getattr(*args)
def guarded_getitem(self, ob, index):
return guarded_getitem(ob, index)
# This does not respect the security policy as set by AccessControl. Instead
# it only deals with the C module being compiled or not.
try:
from AccessControl.cAccessControl import RestrictedDTMLMixin
except ImportError:
RestrictedDTML = BaseRestrictedDTML
else:
class RestrictedDTML(RestrictedDTMLMixin, BaseRestrictedDTML):
"""C version of RestrictedDTML."""
# Add security testing capabilities
from AccessControl import SecurityManagement
class DTMLSecurityAPI:
"""API for performing security checks in DTML using '_' methods.
"""
def SecurityValidate(md, inst, parent, name, value):
"""Validate access.
Arguments:
accessed -- the object that was being accessed
container -- the object the value was found in
name -- The name used to access the value
value -- The value retrieved though the access.
The arguments may be provided as keyword arguments. Some of these
arguments may be ommitted, however, the policy may reject access
in some cases when arguments are ommitted. It is best to provide
all the values possible.
"""
return (SecurityManagement
.getSecurityManager()
.validate(inst, parent, name, value)
)
def SecurityCheckPermission(md, permission, object):
"""Check whether the security context allows the given permission on
the given object.
Arguments:
permission -- A permission name
object -- The object being accessed according to the permission
"""
return (SecurityManagement
.getSecurityManager()
.checkPermission(permission, object)
)
def SecurityGetUser(md):
"""Gen the current authenticated user"""
return (SecurityManagement
.getSecurityManager()
.getUser()
)
def SecurityCalledByExecutable(md):
"""Return a boolean value indicating if this context was called
by an executable"""
r = (SecurityManagement
.getSecurityManager()
.calledByExecutable()
)
if r > 0: return r-1
return r
from DocumentTemplate import DT_Util
for name, v in DTMLSecurityAPI.__dict__.items():
if name[0] != '_':
setattr(DT_Util.TemplateDict, name, v)
from types import FunctionType
from AccessControl.ZopeGuards import safe_builtins
for name, v in safe_builtins.items():
if type(v) is FunctionType:
v = DT_Util.NotBindable(v)
if name.startswith('__'):
continue
setattr(DT_Util.TemplateDict, name, v)
# Temporarily create a DictInstance so that we can mark its type as
# being a key in the ContainerAssertions.
from AccessControl.SimpleObjectPolicies import ContainerAssertions
class _dummy_class:
pass
templateDict = DT_Util.TemplateDict()
try:
dictInstance = templateDict(dummy=1)[0]
if type(dictInstance) is not type(_dummy_class()):
ContainerAssertions[type(dictInstance)]=1
except:
# Hmm, this may cause _() and _.namespace() to fail.
# What to do?
pass
##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# 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
#
##############################################################################
from zope.sequencesort.ssort import *
##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# 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
#
##############################################################################
__allow_access_to_unprotected_subobjects__ = 1
from zope.sequencesort.ssort import *
res1=[{'weight': 1, 'word': 'AAA', 'key': 'aaa'}, {'weight': 0, 'word': 'BBB', 'key': 'bbb'}, {'weight': 0, 'word': 'CCC', 'key': 'ccc'}, {'weight': 0, 'word': 'DDD', 'key': 'ddd'}, {'weight': 1, 'word': 'EEE', 'key': 'eee'}, {'weight': 0, 'word': 'FFF', 'key': 'fff'}, {'weight': 0, 'word': 'GGG', 'key': 'ggg'}, {'weight': 0, 'word': 'HHH', 'key': 'hhh'}, {'weight': 1, 'word': 'III', 'key': 'iii'}, {'weight': -1, 'word': 'JJJ', 'key': 'jjj'}, {'weight': 0, 'word': 'KKK', 'key': 'kkk'}, {'weight': 0, 'word': 'LLL', 'key': 'lll'}, {'weight': 0, 'word': 'MMM', 'key': 'mmm'}, {'weight': 0, 'word': 'NNN', 'key': 'nnn'}, {'weight': 1, 'word': 'OOO', 'key': 'ooo'}, {'weight': 0, 'word': 'PPP', 'key': 'ppp'}, {'weight': -1, 'word': 'QQQ', 'key': 'qqq'}, {'weight': 0, 'word': 'RRR', 'key': 'rrr'}, {'weight': 0, 'word': 'SSS', 'key': 'sss'}, {'weight': 0, 'word': 'TTT', 'key': 'ttt'}, {'weight': 1, 'word': 'UUU', 'key': 'uuu'}, {'weight': 0, 'word': 'VVV', 'key': 'vvv'}, {'weight': 0, 'word': 'WWW', 'key': 'www'}, {'weight': 0, 'word': 'XXX', 'key': 'xxx'}, {'weight': -1, 'word': 'YYY', 'key': 'yyy'}, {'weight': 0, 'word': 'ZZZ', 'key': 'zzz'}]
res2=[{'weight': 1, 'word': 'AAA', 'key': 'aaa'}, {'weight': 0, 'word': 'BBB', 'key': 'bbb'}, {'weight': 0, 'word': 'CCC', 'key': 'ccc'}, {'weight': 0, 'word': 'DDD', 'key': 'ddd'}, {'weight': 1, 'word': 'EEE', 'key': 'eee'}, {'weight': 0, 'word': 'FFF', 'key': 'fff'}, {'weight': 0, 'word': 'GGG', 'key': 'ggg'}, {'weight': 0, 'word': 'HHH', 'key': 'hhh'}, {'weight': 1, 'word': 'III', 'key': 'iii'}, {'weight': -1, 'word': 'JJJ', 'key': 'jjj'}, {'weight': 0, 'word': 'KKK', 'key': 'kkk'}, {'weight': 0, 'word': 'LLL', 'key': 'lll'}, {'weight': 0, 'word': 'MMM', 'key': 'mmm'}, {'weight': 0, 'word': 'NNN', 'key': 'nnn'}, {'weight': 1, 'word': 'OOO', 'key': 'ooo'}, {'weight': 0, 'word': 'PPP', 'key': 'ppp'}, {'weight': -1, 'word': 'QQQ', 'key': 'qqq'}, {'weight': 0, 'word': 'RRR', 'key': 'rrr'}, {'weight': 0, 'word': 'SSS', 'key': 'sss'}, {'weight': 0, 'word': 'TTT', 'key': 'ttt'}, {'weight': 1, 'word': 'UUU', 'key': 'uuu'}, {'weight': 0, 'word': 'VVV', 'key': 'vvv'}, {'weight': 0, 'word': 'WWW', 'key': 'www'}, {'weight': 0, 'word': 'XXX', 'key': 'xxx'}, {'weight': -1, 'word': 'YYY', 'key': 'yyy'}, {'weight': 0, 'word': 'ZZZ', 'key': 'zzz'}]
res3=[{'weight': 1, 'word': 'AAA', 'key': 'aaa'}, {'weight': 0, 'word': 'BBB', 'key': 'bbb'}, {'weight': 0, 'word': 'CCC', 'key': 'ccc'}, {'weight': 0, 'word': 'DDD', 'key': 'ddd'}, {'weight': 1, 'word': 'EEE', 'key': 'eee'}, {'weight': 0, 'word': 'FFF', 'key': 'fff'}, {'weight': 0, 'word': 'GGG', 'key': 'ggg'}, {'weight': 0, 'word': 'HHH', 'key': 'hhh'}, {'weight': 1, 'word': 'III', 'key': 'iii'}, {'weight': -1, 'word': 'JJJ', 'key': 'jjj'}, {'weight': 0, 'word': 'KKK', 'key': 'kkk'}, {'weight': 0, 'word': 'LLL', 'key': 'lll'}, {'weight': 0, 'word': 'MMM', 'key': 'mmm'}, {'weight': 0, 'word': 'NNN', 'key': 'nnn'}, {'weight': 1, 'word': 'OOO', 'key': 'ooo'}, {'weight': 0, 'word': 'PPP', 'key': 'ppp'}, {'weight': -1, 'word': 'QQQ', 'key': 'qqq'}, {'weight': 0, 'word': 'RRR', 'key': 'rrr'}, {'weight': 0, 'word': 'SSS', 'key': 'sss'}, {'weight': 0, 'word': 'TTT', 'key': 'ttt'}, {'weight': 1, 'word': 'UUU', 'key': 'uuu'}, {'weight': 0, 'word': 'VVV', 'key': 'vvv'}, {'weight': 0, 'word': 'WWW', 'key': 'www'}, {'weight': 0, 'word': 'XXX', 'key': 'xxx'}, {'weight': -1, 'word': 'YYY', 'key': 'yyy'}, {'weight': 0, 'word': 'ZZZ', 'key': 'zzz'}]
res4=[{'weight': 0, 'word': 'ZZZ', 'key': 'zzz'}, {'weight': -1, 'word': 'YYY', 'key': 'yyy'}, {'weight': 0, 'word': 'XXX', 'key': 'xxx'}, {'weight': 0, 'word': 'WWW', 'key': 'www'}, {'weight': 0, 'word': 'VVV', 'key': 'vvv'}, {'weight': 1, 'word': 'UUU', 'key': 'uuu'}, {'weight': 0, 'word': 'TTT', 'key': 'ttt'}, {'weight': 0, 'word': 'SSS', 'key': 'sss'}, {'weight': 0, 'word': 'RRR', 'key': 'rrr'}, {'weight': -1, 'word': 'QQQ', 'key': 'qqq'}, {'weight': 0, 'word': 'PPP', 'key': 'ppp'}, {'weight': 1, 'word': 'OOO', 'key': 'ooo'}, {'weight': 0, 'word': 'NNN', 'key': 'nnn'}, {'weight': 0, 'word': 'MMM', 'key': 'mmm'}, {'weight': 0, 'word': 'LLL', 'key': 'lll'}, {'weight': 0, 'word': 'KKK', 'key': 'kkk'}, {'weight': -1, 'word': 'JJJ', 'key': 'jjj'}, {'weight': 1, 'word': 'III', 'key': 'iii'}, {'weight': 0, 'word': 'HHH', 'key': 'hhh'}, {'weight': 0, 'word': 'GGG', 'key': 'ggg'}, {'weight': 0, 'word': 'FFF', 'key': 'fff'}, {'weight': 1, 'word': 'EEE', 'key': 'eee'}, {'weight': 0, 'word': 'DDD', 'key': 'ddd'}, {'weight': 0, 'word': 'CCC', 'key': 'ccc'}, {'weight': 0, 'word': 'BBB', 'key': 'bbb'}, {'weight': 1, 'word': 'AAA', 'key': 'aaa'}]
res5=[{'weight': -1, 'word': 'JJJ', 'key': 'jjj'}, {'weight': -1, 'word': 'QQQ', 'key': 'qqq'}, {'weight': -1, 'word': 'YYY', 'key': 'yyy'}, {'weight': 0, 'word': 'BBB', 'key': 'bbb'}, {'weight': 0, 'word': 'CCC', 'key': 'ccc'}, {'weight': 0, 'word': 'DDD', 'key': 'ddd'}, {'weight': 0, 'word': 'FFF', 'key': 'fff'}, {'weight': 0, 'word': 'GGG', 'key': 'ggg'}, {'weight': 0, 'word': 'HHH', 'key': 'hhh'}, {'weight': 0, 'word': 'KKK', 'key': 'kkk'}, {'weight': 0, 'word': 'LLL', 'key': 'lll'}, {'weight': 0, 'word': 'MMM', 'key': 'mmm'}, {'weight': 0, 'word': 'NNN', 'key': 'nnn'}, {'weight': 0, 'word': 'PPP', 'key': 'ppp'}, {'weight': 0, 'word': 'RRR', 'key': 'rrr'}, {'weight': 0, 'word': 'SSS', 'key': 'sss'}, {'weight': 0, 'word': 'TTT', 'key': 'ttt'}, {'weight': 0, 'word': 'VVV', 'key': 'vvv'}, {'weight': 0, 'word': 'WWW', 'key': 'www'}, {'weight': 0, 'word': 'XXX', 'key': 'xxx'}, {'weight': 0, 'word': 'ZZZ', 'key': 'zzz'}, {'weight': 1, 'word': 'AAA', 'key': 'aaa'}, {'weight': 1, 'word': 'EEE', 'key': 'eee'}, {'weight': 1, 'word': 'III', 'key': 'iii'}, {'weight': 1, 'word': 'OOO', 'key': 'ooo'}, {'weight': 1, 'word': 'UUU', 'key': 'uuu'}]
res6=[{'weight': -1, 'word': 'YYY', 'key': 'yyy'}, {'weight': -1, 'word': 'QQQ', 'key': 'qqq'}, {'weight': -1, 'word': 'JJJ', 'key': 'jjj'}, {'weight': 0, 'word': 'ZZZ', 'key': 'zzz'}, {'weight': 0, 'word': 'XXX', 'key': 'xxx'}, {'weight': 0, 'word': 'WWW', 'key': 'www'}, {'weight': 0, 'word': 'VVV', 'key': 'vvv'}, {'weight': 0, 'word': 'TTT', 'key': 'ttt'}, {'weight': 0, 'word': 'SSS', 'key': 'sss'}, {'weight': 0, 'word': 'RRR', 'key': 'rrr'}, {'weight': 0, 'word': 'PPP', 'key': 'ppp'}, {'weight': 0, 'word': 'NNN', 'key': 'nnn'}, {'weight': 0, 'word': 'MMM', 'key': 'mmm'}, {'weight': 0, 'word': 'LLL', 'key': 'lll'}, {'weight': 0, 'word': 'KKK', 'key': 'kkk'}, {'weight': 0, 'word': 'HHH', 'key': 'hhh'}, {'weight': 0, 'word': 'GGG', 'key': 'ggg'}, {'weight': 0, 'word': 'FFF', 'key': 'fff'}, {'weight': 0, 'word': 'DDD', 'key': 'ddd'}, {'weight': 0, 'word': 'CCC', 'key': 'ccc'}, {'weight': 0, 'word': 'BBB', 'key': 'bbb'}, {'weight': 1, 'word': 'UUU', 'key': 'uuu'}, {'weight': 1, 'word': 'OOO', 'key': 'ooo'}, {'weight': 1, 'word': 'III', 'key': 'iii'}, {'weight': 1, 'word': 'EEE', 'key': 'eee'}, {'weight': 1, 'word': 'AAA', 'key': 'aaa'}]
res7=[{'weight': -1, 'word': 'JJJ', 'key': 'jjj'}, {'weight': -1, 'word': 'QQQ', 'key': 'qqq'}, {'weight': -1, 'word': 'YYY', 'key': 'yyy'}, {'weight': 0, 'word': 'BBB', 'key': 'bbb'}, {'weight': 0, 'word': 'CCC', 'key': 'ccc'}, {'weight': 0, 'word': 'DDD', 'key': 'ddd'}, {'weight': 0, 'word': 'FFF', 'key': 'fff'}, {'weight': 0, 'word': 'GGG', 'key': 'ggg'}, {'weight': 0, 'word': 'HHH', 'key': 'hhh'}, {'weight': 0, 'word': 'KKK', 'key': 'kkk'}, {'weight': 0, 'word': 'LLL', 'key': 'lll'}, {'weight': 0, 'word': 'MMM', 'key': 'mmm'}, {'weight': 0, 'word': 'NNN', 'key': 'nnn'}, {'weight': 0, 'word': 'PPP', 'key': 'ppp'}, {'weight': 0, 'word': 'RRR', 'key': 'rrr'}, {'weight': 0, 'word': 'SSS', 'key': 'sss'}, {'weight': 0, 'word': 'TTT', 'key': 'ttt'}, {'weight': 0, 'word': 'VVV', 'key': 'vvv'}, {'weight': 0, 'word': 'WWW', 'key': 'www'}, {'weight': 0, 'word': 'XXX', 'key': 'xxx'}, {'weight': 0, 'word': 'ZZZ', 'key': 'zzz'}, {'weight': 1, 'word': 'AAA', 'key': 'aaa'}, {'weight': 1, 'word': 'EEE', 'key': 'eee'}, {'weight': 1, 'word': 'III', 'key': 'iii'}, {'weight': 1, 'word': 'OOO', 'key': 'ooo'}, {'weight': 1, 'word': 'UUU', 'key': 'uuu'}]
##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# 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
#
##############################################################################
import unittest
from DocumentTemplate.sequence.SortEx import *
from DocumentTemplate.sequence.tests.ztestlib import *
from DocumentTemplate.sequence.tests.results import *
class TestCase( unittest.TestCase ):
"""
Test SortEx .
"""
def setUp( self ):
"""
"""
def tearDown( self ):
"""
"""
def test1( self ):
"test1"
assert res1==SortEx(wordlist)
def test2( self ):
"test2"
assert res2==SortEx(wordlist, (("key",),), mapping=1)
def test3( self ):
"test3"
assert res3==SortEx(wordlist, (("key", "cmp"),), mapping=1)
def test4( self ):
"test4"
assert res4==SortEx(wordlist, (("key", "cmp", "desc"),), mapping=1)
def test5( self ):
"test5"
assert res5==SortEx(wordlist, (("weight",), ("key",)), mapping=1)
def test6( self ):
"test6"
assert res6==SortEx(wordlist, (("weight",), ("key", "nocase", "desc")), mapping=1)
def test7(self):
"test7"
def myCmp(s1, s2):
return -cmp(s1, s2)
# Create namespace...
from DocumentTemplate.DT_Util import TemplateDict
md = TemplateDict()
#... and push out function onto the namespace
md._push({"myCmp" : myCmp})
assert res7==SortEx( wordlist
, ( ("weight",)
, ("key", "myCmp", "desc")
)
, md
, mapping=1
)
def test_suite():
suite = unittest.TestSuite()
suite.addTest( unittest.makeSuite( TestCase ) )
return suite
def main():
unittest.TextTestRunner().run(test_suite())
if __name__ == '__main__':
main()
class standard_html: # Base class for using with ZTemplates
def __init__(self, title):
self.standard_html_header = """<HTML>
<HEAD>
<TITLE>
%s
</TITLE>
</HEAD>
<BODY>""" % title
self.standard_html_footer = """</BODY>
</HTML>"""
self.title = title
def test(s):
outfile = open("test.out", 'w')
outfile.write(s)
outfile.close()
def exception():
import sys, traceback
exc_type, exc_value, exc_tb = sys.exc_info()
outfile = open("test.err", 'w')
traceback.print_exception(exc_type, exc_value, exc_tb, None, outfile)
outfile.close()
wordlist = [
{"key": "aaa", "word": "AAA", "weight": 1},
{"key": "bbb", "word": "BBB", "weight": 0},
{"key": "ccc", "word": "CCC", "weight": 0},
{"key": "ddd", "word": "DDD", "weight": 0},
{"key": "eee", "word": "EEE", "weight": 1},
{"key": "fff", "word": "FFF", "weight": 0},
{"key": "ggg", "word": "GGG", "weight": 0},
{"key": "hhh", "word": "HHH", "weight": 0},
{"key": "iii", "word": "III", "weight": 1},
{"key": "jjj", "word": "JJJ", "weight": -1},
{"key": "kkk", "word": "KKK", "weight": 0},
{"key": "lll", "word": "LLL", "weight": 0},
{"key": "mmm", "word": "MMM", "weight": 0},
{"key": "nnn", "word": "NNN", "weight": 0},
{"key": "ooo", "word": "OOO", "weight": 1},
{"key": "ppp", "word": "PPP", "weight": 0},
{"key": "qqq", "word": "QQQ", "weight": -1},
{"key": "rrr", "word": "RRR", "weight": 0},
{"key": "sss", "word": "SSS", "weight": 0},
{"key": "ttt", "word": "TTT", "weight": 0},
{"key": "uuu", "word": "UUU", "weight": 1},
{"key": "vvv", "word": "VVV", "weight": 0},
{"key": "www", "word": "WWW", "weight": 0},
{"key": "xxx", "word": "XXX", "weight": 0},
{"key": "yyy", "word": "YYY", "weight": -1},
{"key": "zzz", "word": "ZZZ", "weight": 0}
]
<html><head><title>Inventory by Dealer</title></head><body>
<dl>
<dtml-in inventory mapping size=5 start=first_ad orphan=3>
<dtml-if previous-sequence>
<dtml-in previous-batches mapping>
(<dtml-var batch-start-var-dealer> <dtml-var
batch-start-var-year> <dtml-var
batch-start-var-make> <dtml-var
batch-start-var-model> - <dtml-var
batch-end-var-dealer> <dtml-var
batch-end-var-year> <dtml-var
batch-end-var-make> <dtml-var
batch-end-var-model>)
</dtml-in previous-batches>
</dtml-if previous-sequence>
<dtml-if first-dealer>
<dt><dtml-var dealer></dt><dd>
</dtml-if first-dealer>
<dtml-var year> <dtml-var make> <dtml-var model> <p>
<dtml-if last-dealer>
</dd>
</dtml-if last-dealer>
<dtml-if next-sequence>
<dtml-in next-batches mapping>
(<dtml-var batch-start-var-dealer> <dtml-var
batch-start-var-year> <dtml-var
batch-start-var-make> <dtml-var
batch-start-var-model> - <dtml-var
batch-end-var-dealer> <dtml-var
batch-end-var-year> <dtml-var
batch-end-var-make> <dtml-var
batch-end-var-model>)
</dtml-in next-batches>
</dtml-if next-sequence>
</dtml-in inventory>
</dl>
</body></html>
<html><head><title>Inventory by Dealer</title></head><body>
<dl>
(Bay Chevy 96 Chevrolet Caprice - Bay Chevy 96 Chevrolet Nova)
(Bay Chevy 96 Chevrolet Corvett - Bay Chevy 96 Chevrolet Corsica)
(Bay Chevy 96 Chevrolet Corsica - Colman Olds 96 Olds Ciera)
<dt>Colman Olds</dt><dd>
96 Olds Cutlass <p>
95 Olds Cutlas <p>
93 Dodge Shadow <p>
94 Jeep Cheroke <p>
92 Toyota Previa <p>
</dd>
(Colman Olds 93 Toyota Celica - Colman Olds 94 Honda Civic)
(Colman Olds 93 Honda Civix - Spam Chev 96 Chevrolet Nova)
(Spam Chev 96 Chevrolet Corvett - Spam Chev 96 Chevrolet Corsica)
(Spam Chev 96 Chevrolet Corsica - Spam Olds 96 Olds Ciera)
(Spam Olds 96 Olds Cutlass - Spam Olds 92 Toyota Previa)
(Spam Olds 93 Toyota Celica - Spam Olds 93 Honda Civix)
</dl>
</body></html>
This diff is collapsed.
##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# 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
#
##############################################################################
"""Document Template Tests
"""
import unittest
class force_str:
# A class whose string representation is not always a plain string:
def __init__(self,s):
self.s = s
def __str__(self):
return self.s
class DTMLUnicodeTests (unittest.TestCase):
def _get_doc_class(self):
from DocumentTemplate.DT_HTML import HTML
return HTML
doc_class = property(_get_doc_class,)
def testAA(self):
html=self.doc_class('<dtml-var a><dtml-var b>')
expected = 'helloworld'
res = html(a='hello',b='world')
assert res == expected, `res`
def testUU(self):
html=self.doc_class('<dtml-var a><dtml-var b>')
expected = u'helloworld'
res = html(a=u'hello',b=u'world')
assert res == expected, `res`
def testAU(self):
html=self.doc_class('<dtml-var a><dtml-var b>')
expected = u'helloworld'
res = html(a='hello',b=u'world')
assert res == expected, `res`
def testAB(self):
html=self.doc_class('<dtml-var a><dtml-var b>')
expected = 'hello\xc8'
res = html(a='hello',b=chr(200))
assert res == expected, `res`
def testUB(self):
html=self.doc_class('<dtml-var a><dtml-var b>')
expected = u'hello\xc8'
res = html(a=u'hello',b=chr(200))
assert res == expected, `res`
def testUB2(self):
html=self.doc_class('<dtml-var a><dtml-var b>')
expected = u'\u07d0\xc8'
res = html(a=unichr(2000),b=chr(200))
assert res == expected, `res`
def testUnicodeStr(self):
html=self.doc_class('<dtml-var a><dtml-var b>')
expected = u'\u07d0\xc8'
res = html(a=force_str(unichr(2000)),b=chr(200))
assert res == expected, `res`
def testUqB(self):
html=self.doc_class('<dtml-var a html_quote><dtml-var b>')
expected = u'he&gt;llo\xc8'
res = html(a=u'he>llo',b=chr(200))
assert res == expected, `res`
def testSize(self):
html=self.doc_class('<dtml-var "_.unichr(200)*4" size=2>')
expected = unichr(200)*2+'...'
res = html()
assert res == expected, `res`
def test_suite():
suite = unittest.TestSuite()
suite.addTest( unittest.makeSuite( DTMLUnicodeTests ) )
return suite
##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# 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
#
##############################################################################
"""Document Template Tests
"""
import unittest
from DocumentTemplate import HTML
from DocumentTemplate.tests.testDTML import DTMLTests
from DocumentTemplate.security import RestrictedDTML
from AccessControl import Unauthorized
from AccessControl.SecurityManagement import getSecurityManager
from ExtensionClass import Base
class UnownedDTML(RestrictedDTML, HTML):
def getOwner(self):
return None
def __call__(self, client=None, REQUEST={}, RESPONSE=None, **kw):
"""Render the DTML"""
security = getSecurityManager()
security.addContext(self)
try:
return HTML.__call__(self, client, REQUEST, **kw)
finally:
security.removeContext(self)
class SecurityTests(DTMLTests):
doc_class = UnownedDTML
unrestricted_doc_class = HTML
def testNoImplicitAccess(self):
class person:
name='Jim'
doc = self.doc_class(
'<dtml-with person>Hi, my name is '
'<dtml-var name></dtml-with>')
try:
doc(person=person())
except Unauthorized:
# Passed the test.
pass
else:
assert 0, 'Did not protect class instance'
def testExprExplicitDeny(self):
class myclass (Base):
__roles__ = None # Public
somemethod__roles__ = () # Private
def somemethod(self):
return "This is a protected operation of public object"
html = self.doc_class('<dtml-var expr="myinst.somemethod()">')
self.failUnlessRaises(Unauthorized, html, myinst=myclass())
def testSecurityInSyntax(self):
# Ensures syntax errors are thrown for an expr with restricted
# syntax.
expr = '<dtml-var expr="(lambda x, _read=(lambda ob:ob): x.y)(c)">'
try:
# This would be a security hole.
html = self.doc_class(expr) # It might compile here...
html() # or it might compile here.
except SyntaxError:
# Passed the test.
pass
else:
assert 0, 'Did not catch bad expr'
# Now be sure the syntax error occurred for security purposes.
html = self.unrestricted_doc_class(expr)
class c:
y = 10
res = html(c=c)
assert res == '10', res
def testNewDTMLBuiltins(self):
NEW_BUILTINS_TEMPLATE = """
<dtml-var expr="_.min([1,2])">
<dtml-var expr="_.max([2,3])">
<dtml-var expr="_.sum([1,2,3,4])">
<dtml-var expr="_.hasattr(1, 'foo') and 'Yes' or 'No'">
<dtml-var expr="_.None">
<dtml-var expr="_.string.strip(' testing ')">
<dtml-var expr="[x for x in (1, 2, 3)]">
"""
EXPECTED = ['1', '3', '10', 'No', 'None', 'testing', '[1, 2, 3]']
#
# XXX: these expressions seem like they should work, with
# the following ExPECTED, but they raise Unauthorized
# on the 'next' name.
#
#<dtml-var expr="_.iter([1,2,3]).next()">
#<dtml-var expr="_.enumerate([1,2,3]).next()">
#
#EXPECTED = ['1', '3', '10', '1', '(0, 1)']
template = self.doc_class(NEW_BUILTINS_TEMPLATE)
res = template()
lines = filter(None, [x.strip() for x in res.split('\n')])
self.assertEqual(lines, EXPECTED)
# Note: we need more tests!
def test_suite():
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(SecurityTests))
return suite
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -36,8 +36,8 @@ class p_:
davlocked=ImageFile('webdav/www/davlock.gif')
pl=ImageFile('TreeDisplay/www/Plus_icon.gif')
mi=ImageFile('TreeDisplay/www/Minus_icon.gif')
pl=ImageFile('OFS/www/Plus_icon.gif')
mi=ImageFile('OFS/www/Minus_icon.gif')
rtab=ImageFile('App/www/rtab.gif')
ltab=ImageFile('App/www/ltab.gif')
sp =ImageFile('App/www/sp.gif')
......
This diff is collapsed.
This diff is collapsed.
......@@ -7,6 +7,7 @@ Zope2 =
AccessControl = 2.13.1
Acquisition = 2.13.3
DateTime = 2.12.2
DocumentTemplate = 2.13.0
ExtensionClass = 2.13.2
initgroups = 2.13.0
Missing = 2.13.1
......
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