Commit 8ad03a70 authored by Jim Fulton's avatar Jim Fulton

many changes for thread safety, bug fixes, and faster import

parent 6ed3361e
##############################################################################
#
# Copyright (c) 1998, Digital Creations, Fredericksburg, VA, USA.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# o Redistributions of source code must retain the above copyright
# notice, this list of conditions, and the disclaimer that follows.
#
# o Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions, and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# o All advertising materials mentioning features or use of this
# software must display the following acknowledgement:
#
# This product includes software developed by Digital Creations
# and its contributors.
#
# o Neither the name of Digital Creations nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
#
# THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS AND CONTRIBUTORS *AS IS*
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL
# CREATIONS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
# DAMAGE.
#
#
# If you have questions regarding this software, contact:
#
# Digital Creations, L.C.
# 910 Princess Ann Street
# Fredericksburge, Virginia 22401
#
# info@digicool.com
#
# (540) 371-6909
#
##############################################################################
__doc__='''Comments
The 'comment' tag can be used to simply include comments
in DTML source.
For example::
<!--#comment-->
This text is not rendered.
<!--#/comment-->
'''
__rcs_id__='$Id: DT_Comment.py,v 1.3 1998/09/02 14:35:51 jim Exp $'
__version__='$Revision: 1.3 $'[11:-2]
from DT_Util import *
from string import find, split, join
class Comment:
name='comment'
blockContinuations=()
def __init__(self, args, fmt=''): pass
def render(self, md):
return ''
__call__=render
############################################################################
# $Log: DT_Comment.py,v $
# Revision 1.3 1998/09/02 14:35:51 jim
# open source copyright
#
# Revision 1.2 1998/04/02 17:37:34 jim
# Major redesign of block rendering. The code inside a block tag is
# compiled as a template but only the templates blocks are saved, and
# later rendered directly with render_blocks.
#
# Added with tag.
#
# Also, for the HTML syntax, we now allow spaces after # and after end
# or '/'. So, the tags::
#
# <!--#
# with spam
# -->
#
# and::
#
# <!--#
# end with
# -->
#
# are valid.
#
# Revision 1.1 1998/03/04 18:19:56 jim
# added comment and raise tags
#
#
This diff is collapsed.
......@@ -54,12 +54,11 @@
"""HTML formated DocumentTemplates
$Id: DT_HTML.py,v 1.8 1998/09/02 14:35:52 jim Exp $"""
$Id: DT_HTML.py,v 1.9 1998/09/02 21:06:03 jim Exp $"""
from DT_String import String, FileMixin
import DT_Doc, DT_String, regex
from DT_Util import *
from regsub import gsub
import DT_String, regex
from DT_Util import ParseError
from string import strip, find, split, join
class dtml_re_class:
......@@ -109,7 +108,19 @@ class dtml_re_class:
class HTML(DT_String.String):
__doc__=DT_Doc.HTML__doc__
"""HTML Document Templates
HTML Document templates use HTML server-side-include syntax,
rather than Python format-string syntax. Here's a simple example:
<!--#in results-->
<!--#var name-->
<!--#/in-->
HTML document templates quote HTML tags in source when the
template is converted to a string. This is handy when templates
are inserted into HTML editing forms.
"""
def tagre(self):
return dtml_re_class()
......
......@@ -117,11 +117,10 @@ __doc__='''Conditional insertion
variable is not reevaluated.
'''
__rcs_id__='$Id: DT_If.py,v 1.10 1998/09/02 14:35:52 jim Exp $'
__version__='$Revision: 1.10 $'[11:-2]
__rcs_id__='$Id: DT_If.py,v 1.11 1998/09/02 21:06:03 jim Exp $'
__version__='$Revision: 1.11 $'[11:-2]
from DT_Util import *
import sys
from DT_Util import ParseError, parse_params, name_param
class If:
blockContinuations='else','elif'
......@@ -185,6 +184,9 @@ class Else(Unless):
##########################################################################
#
# $Log: DT_If.py,v $
# Revision 1.11 1998/09/02 21:06:03 jim
# many changes for thread safety, bug fixes, and faster import
#
# Revision 1.10 1998/09/02 14:35:52 jim
# open source copyright
#
......
......@@ -349,14 +349,15 @@
''' #'
__rcs_id__='$Id: DT_In.py,v 1.26 1998/09/02 14:35:52 jim Exp $'
__version__='$Revision: 1.26 $'[11:-2]
__rcs_id__='$Id: DT_In.py,v 1.27 1998/09/02 21:06:04 jim Exp $'
__version__='$Revision: 1.27 $'[11:-2]
from DT_Util import *
from DT_Util import ParseError, parse_params, name_param
from DT_Util import render_blocks, InstanceDict
from string import find, atoi, join
import ts_regex
from regsub import gsub
from DT_InSV import sequence_variables, opt
TupleType=type(())
class InFactory:
blockContinuations=('else',)
......@@ -677,19 +678,21 @@ class InClass:
basic_type={type(''): 1, type(0): 1, type(0.0): 1, type(()): 1, type([]): 1
}.has_key
def int_param(params,md,name,default=0):
def int_param(params,md,name,default=0, st=type('')):
try: v=params[name]
except: v=default
if v:
try: v=atoi(v)
except:
v=md[v]
if type(v)==types.StringType:
v=atoi(v)
if type(v) is st: v=atoi(v)
return v
############################################################################
# $Log: DT_In.py,v $
# Revision 1.27 1998/09/02 21:06:04 jim
# many changes for thread safety, bug fixes, and faster import
#
# Revision 1.26 1998/09/02 14:35:52 jim
# open source copyright
#
......
......@@ -65,11 +65,10 @@
<!--#/if-->
'''
__rcs_id__='$Id: DT_Raise.py,v 1.5 1998/09/02 14:35:53 jim Exp $'
__version__='$Revision: 1.5 $'[11:-2]
__rcs_id__='$Id: DT_Raise.py,v 1.6 1998/09/02 21:06:04 jim Exp $'
__version__='$Revision: 1.6 $'[11:-2]
from DT_Util import *
import sys
from DT_Util import parse_params, name_param, render_blocks
class Raise:
blockContinuations=()
......@@ -104,6 +103,9 @@ class Raise:
##########################################################################
#
# $Log: DT_Raise.py,v $
# Revision 1.6 1998/09/02 21:06:04 jim
# many changes for thread safety, bug fixes, and faster import
#
# Revision 1.5 1998/09/02 14:35:53 jim
# open source copyright
#
......
......@@ -51,17 +51,33 @@
# (540) 371-6909
#
##############################################################################
"$Id: DT_String.py,v 1.14 1998/09/02 14:35:53 jim Exp $"
"$Id: DT_String.py,v 1.15 1998/09/02 21:06:04 jim Exp $"
from string import *
import DT_Doc, DT_Var, DT_In, DT_If, regex, ts_regex, DT_Raise, DT_With
Var=DT_Var.Var
from string import split, strip
import regex, ts_regex
from DT_Util import ParseError, InstanceDict, TemplateDict, render_blocks
from DT_Var import Var, Call, Comment
from DT_Util import *
from DT_Comment import Comment
class String:
__doc__=DT_Doc.String__doc__
"""Document templates defined from strings.
Document template strings use an extended form of python string
formatting. To insert a named value, simply include text of the
form: '%(name)x', where 'name' is the name of the value and 'x' is
a format specification, such as '12.2d'.
To intrduce a block such as an 'if' or an 'in' or a block continuation,
such as an 'else', use '[' as the format specification. To
terminate a block, ise ']' as the format specification, as in::
%(in results)[
%(name)s
%(in results)]
"""
isDocTemp=1
# Document Templates masquerade as functions:
......@@ -79,15 +95,15 @@ class String:
self.errQuote(self.__name__))
commands={
'var': DT_Var.Var,
'call': DT_Var.Call,
'in': DT_In.In,
'with': DT_With.With,
'if': DT_If.If,
'unless': DT_If.Unless,
'else': DT_If.Else,
'var': Var,
'call': Call,
'in': ('in', 'DT_In','In'),
'with': ('with', 'DT_With','With'),
'if': ('if', 'DT_If','If'),
'unless': ('unless', 'DT_If','Unless'),
'else': ('else', 'DT_If','Else'),
'comment': Comment,
'raise': DT_Raise.Raise,
'raise': ('raise', 'DT_Raise','Raise'),
}
def SubTemplate(self, name): return String('', __name__=name)
......@@ -103,6 +119,16 @@ class String:
')\(<fmt>[0-9]*[.]?[0-9]*[a-z]\|[]![]\)' # end
, regex.casefold)
def _parseTag(self, tagre, command=None, sargs='', tt=type(())):
tag, args, command, coname = self.parseTag(tagre,command,sargs)
if type(command) is tt:
cname, module, name = command
d={}
exec 'from %s import %s' % (module, name) in d
command=d[name]
self.commands[cname]=command
return tag, args, command, coname
def parseTag(self, tagre, command=None, sargs=''):
"""Parse a tag using an already matched re
......@@ -151,7 +177,7 @@ class String:
l=tagre.search(text,start)
while l >= 0:
try: tag, args, command, coname = self.parseTag(tagre)
try: tag, args, command, coname = self._parseTag(tagre)
except ParseError, m: self.parse_error(m[0],m[1],text,l)
s=text[start:l]
......@@ -196,7 +222,7 @@ class String:
l=tagre.search(text,start)
if l < 0: self.parse_error('No closing tag', stag, text, sloc)
try: tag, args, command, coname= self.parseTag(tagre,scommand,sa)
try: tag, args, command, coname= self._parseTag(tagre,scommand,sa)
except ParseError, m: self.parse_error(m[0],m[1], text, l)
if command:
......@@ -233,7 +259,7 @@ class String:
l=tagre.search(text,start)
if l < 0: self.parse_error('No closing tag', stag, text, sloc)
try: tag, args, command, coname= self.parseTag(tagre,scommand,sa)
try: tag, args, command, coname= self._parseTag(tagre,scommand,sa)
except ParseError, m: self.parse_error(m[0],m[1], text, l)
start=l+len(tag)
......@@ -297,7 +323,7 @@ class String:
self.initvars(mapping, vars)
if source_string is not None:
self.raw=source_string
self.cooked=self.cook()
self.cook()
def manage_edit(self,data,REQUEST=None):
self.munge(data)
......@@ -308,8 +334,15 @@ class String:
def read(self,raw=None):
return self.read_raw()
def cook(self):
self.blocks=self.parse(self.read())
def cook(self,
cooklock=ts_regex.allocate_lock(),
):
cooklock.acquire()
try:
self.blocks=self.parse(self.read())
self.cooked=None
finally:
cooklock.release()
def initvars(self, globals, vars):
if globals:
......@@ -384,8 +417,7 @@ class String:
if not hasattr(self,'cooked'):
try: changed=self.__changed__()
except: changed=1
cooked=self.cook()
self.cooked=cooked
self.cook()
if not changed: self.__changed__(0)
pushed=None
......
......@@ -51,28 +51,36 @@
# (540) 371-6909
#
##############################################################################
'''$Id: DT_Util.py,v 1.41 1998/09/02 14:35:54 jim Exp $'''
__version__='$Revision: 1.41 $'[11:-2]
import sys, regex, string, types, math, os
from string import rfind, strip, joinfields, atoi,lower,upper,capitalize
from types import *
from regsub import gsub, sub, split
from __builtin__ import *
'''$Id: DT_Util.py,v 1.42 1998/09/02 21:06:05 jim Exp $'''
__version__='$Revision: 1.42 $'[11:-2]
import regex, string, math, os
from string import rfind, strip, join, atoi,lower,upper,capitalize,split,find
import VSEval
ParseError='Document Template Parse Error'
ValidationError='Unauthorized'
def int_param(params,md,name,default=0):
def html_quote(v, name='(Unknown name)', md={},
character_entities=(
(('&'), '&amp;'),
(("<"), '&lt;' ),
((">"), '&gt;' ),
(('"'), '&quot;'))): #"
text=str(v)
for re,name in character_entities:
if find(text, re) >= 0: text=join(split(text,re),name)
return text
def int_param(params,md,name,default=0, st=type('')):
try: v=params[name]
except: v=default
if v:
try: v=atoi(v)
except:
v=md[v]
if type(v)==types.StringType:
v=atoi(v)
if type(v) is st: v=atoi(v)
return v
def careful_getattr(md, inst, name):
......@@ -409,167 +417,3 @@ def parse_params(text,
text=strip(text[l:])
if text: return apply(parse_params,(text,result),parms)
else: return result
############################################################################
# $Log: DT_Util.py,v $
# Revision 1.41 1998/09/02 14:35:54 jim
# open source copyright
#
# Revision 1.40 1998/08/05 18:26:27 jim
# Improved handling of expr syntax errors. Could be better, but code
# is dependent on Python version.
#
# Revision 1.39 1998/07/29 15:35:27 jim
# Fixed bug in handling "..." shorthand.
#
# Revision 1.38 1998/07/27 23:42:12 jim
# Revamped attribute parsing to:
#
# - Handle valueless attributes a bit better.
# In particular, if a valueless parameter is not
# in the first position, it is not confused for a name,
#
# - Added "..." shorthand for exprs, so now you can:
#
# <!--#if "x < 1"-->
#
# Revision 1.37 1998/05/20 17:54:34 jim
# Fixed obsolete stupid attr function. Blech.
#
# Revision 1.36 1998/05/14 16:30:49 jim
# Added render function.
#
# Revision 1.35 1998/05/13 22:15:27 jim
# Updated doc string.
#
# Revision 1.34 1998/05/13 22:06:31 jim
# Updated doc string.
#
# Revision 1.33 1998/05/13 21:50:14 jim
# Moved special trick to handle _=_vars here so as to not break other uses
# of VSEval.
#
# Revision 1.32 1998/05/13 21:09:23 jim
# Changed the way that '_' is handled. It is now an alias for the template dict.
#
# Revision 1.31 1998/04/02 17:37:37 jim
# Major redesign of block rendering. The code inside a block tag is
# compiled as a template but only the templates blocks are saved, and
# later rendered directly with render_blocks.
#
# Added with tag.
#
# Also, for the HTML syntax, we now allow spaces after # and after end
# or '/'. So, the tags::
#
# <!--#
# with spam
# -->
#
# and::
#
# <!--#
# end with
# -->
#
# are valid.
#
# Revision 1.30 1998/03/26 22:02:16 jim
# Changed value of ValidationError to Unauthorized.
#
# Revision 1.29 1998/03/26 16:09:11 jim
# *** empty log message ***
#
# Revision 1.28 1998/03/26 16:05:46 jim
# *** empty log message ***
#
# Revision 1.27 1998/03/26 14:59:29 jim
# Fixed bug in exporting rand modules.
#
# Revision 1.26 1998/03/12 20:52:11 jim
# Added namespace function to _ module for exprs.
#
# Revision 1.25 1998/03/10 15:04:58 jim
# Added better handling of case like:
#
# <!--#in expr="whatever" mapping-->
#
# Revision 1.24 1998/03/06 23:22:36 jim
# Added "builtin" 'attr' function: attr(inst,name,_vars)
#
# Revision 1.23 1998/03/04 18:18:40 jim
# Extended the parse_name utility to handle other name-like tags.
#
# Revision 1.22 1998/01/13 19:35:55 jim
# Added rand and whrand.
#
# Revision 1.21 1998/01/12 16:48:40 jim
# Fixed error reporting bug.
#
# Revision 1.20 1997/11/27 00:10:50 jim
# Hacked my way out of using new module.
#
# Revision 1.19 1997/11/25 15:26:34 jim
# Added test to expr documentation.
#
# Revision 1.18 1997/11/25 15:20:30 jim
# Expanded test function to allow any number of arguments.
#
# Revision 1.17 1997/11/19 15:42:47 jim
# added _ prefix to push and pop methods to make them private
#
# Revision 1.16 1997/11/19 15:33:32 jim
# Updated parse_params so that you can define an attribute that, if
# used, must have a value. This is done by specifying None as a default
# value.
#
# Revision 1.15 1997/11/12 19:44:13 jim
# Took out setting __roles__ for pop and push.
#
# Revision 1.14 1997/11/11 18:13:48 jim
# updated expr machinery to use parse-tree manipulation
#
# Revision 1.13 1997/10/29 22:06:06 jim
# Moved func_code from DT_Util to DT_String.
#
# Took stab at expression documentation.
#
# Revision 1.12 1997/10/29 21:30:24 jim
# Added "builtin" objects.
#
# Revision 1.11 1997/10/29 21:03:26 jim
# *** empty log message ***
#
# Revision 1.10 1997/10/29 20:43:24 jim
# *** empty log message ***
#
# Revision 1.9 1997/10/29 16:58:30 jim
# Modified to explicitly make push and pop private.
#
# Revision 1.8 1997/10/29 16:17:45 jim
# Added careful_getslice.
#
# Revision 1.7 1997/10/28 22:10:46 jim
# changed 'acquire' to 'aq_acquire'.
#
# Revision 1.6 1997/10/28 21:50:01 jim
# Updated validation rules to use DT validation method.
#
# Revision 1.5 1997/10/27 17:38:41 jim
# Added some new experimental validation machinery.
# This is, still a work in progress.
#
# Fixed some error generation bugs.
#
# Revision 1.4 1997/09/25 18:56:39 jim
# fixed problem in reporting errors
#
# Revision 1.3 1997/09/22 14:42:50 jim
# added expr
#
# Revision 1.2 1997/09/02 20:35:09 jim
# Various fixes to parsing code.
#
# Revision 1.1 1997/08/27 18:55:43 jim
# initial
#
......@@ -164,11 +164,11 @@ Evaluating expressions without rendering results
''' # '
__rcs_id__='$Id: DT_Var.py,v 1.16 1998/09/02 14:35:54 jim Exp $'
__version__='$Revision: 1.16 $'[11:-2]
__rcs_id__='$Id: DT_Var.py,v 1.17 1998/09/02 21:06:05 jim Exp $'
__version__='$Revision: 1.17 $'[11:-2]
from DT_Util import *
import ts_regex
from DT_Util import parse_params, name_param, html_quote
import regex, string, sys, regex
from string import find, split, join
class Var:
......@@ -277,24 +277,15 @@ class Call:
self.simple_form=expr,None
def html_quote(v, name='(Unknown name)', md={},
character_entities=(
(('&'), '&amp;'),
(("<"), '&lt;' ),
((">"), '&gt;' ),
(('"'), '&quot;'))): #"
text=str(v)
for re,name in character_entities:
if find(text, re) >= 0: text=join(split(text,re),name)
return text
def url_quote(v, name='(Unknown name)', md={}):
import urllib
return urllib.quote(str(v))
def newline_to_br(v, name='(Unknown name)', md={},
nl=ts_regex.compile('\r?\n')):
return gsub(nl,'<br>\n',str(v))
def newline_to_br(v, name='(Unknown name)', md={}):
v=str(v)
if find(v,'\r') >= 0: v=join(split(v,'\r'),'')
if find(v,'\n') >= 0: v=join(split(v,'\n'),'<br>\n')
return v
def whole_dollars(v, name='(Unknown name)', md={}):
try: return "$%d" % v
......@@ -305,11 +296,20 @@ def dollars_and_cents(v, name='(Unknown name)', md={}):
except: return ''
def thousands_commas(v, name='(Unknown name)', md={},
thou=ts_regex.compile("\([0-9]\)\([0-9][0-9][0-9]\([,.]\|$\)\)")):
thou=regex.compile(
"\([0-9]\)\([0-9][0-9][0-9]\([,.]\|$\)\)").search):
v=str(v)
while thou.search(v) >= 0:
v=sub(thou,"\\1,\\2",v)
return v
vl=split(v,'.')
if not vl: return v
v=vl[0]
del vl[0]
if vl: s='.'+join(vl,'.')
else: s=''
l=thou(v)
while l >= 0:
v=v[:l+1]+','+v[l+1:]
l=thou(v)
return v+s
def whole_dollars_with_commas(v, name='(Unknown name)', md={}):
try: v= "$%d" % v
......@@ -360,13 +360,39 @@ special_formats={
def spacify(val): return gsub('_', ' ', val)
modifiers=(html_quote, url_quote, newline_to_br, lower, upper,
capitalize, spacify, thousands_commas, sql_quote)
modifiers=(html_quote, url_quote, newline_to_br, string.lower, string.upper,
string.capitalize, spacify, thousands_commas, sql_quote)
modifiers=map(lambda f: (f.__name__, f), modifiers)
class Comment:
'''Comments
The 'comment' tag can be used to simply include comments
in DTML source.
For example::
<!--#comment-->
This text is not rendered.
<!--#/comment-->
'''
name='comment'
blockContinuations=()
def __init__(self, args, fmt=''): pass
def render(self, md):
return ''
__call__=render
############################################################################
# $Log: DT_Var.py,v $
# Revision 1.17 1998/09/02 21:06:05 jim
# many changes for thread safety, bug fixes, and faster import
#
# Revision 1.16 1998/09/02 14:35:54 jim
# open source copyright
#
......
......@@ -75,10 +75,10 @@
'''
__rcs_id__='$Id: DT_With.py,v 1.2 1998/09/02 14:35:55 jim Exp $'
__version__='$Revision: 1.2 $'[11:-2]
__rcs_id__='$Id: DT_With.py,v 1.3 1998/09/02 21:06:06 jim Exp $'
__version__='$Revision: 1.3 $'[11:-2]
from DT_Util import *
from DT_Util import parse_params, name_param, InstanceDict, render_blocks
class With:
blockContinuations=()
......
......@@ -55,8 +55,8 @@
"""Document Template Tests
"""
__rcs_id__='$Id: DTtest.py,v 1.6 1998/09/02 14:35:55 jim Exp $'
__version__='$Revision: 1.6 $'[11:-2]
__rcs_id__='$Id: DTtest.py,v 1.7 1998/09/02 21:06:06 jim Exp $'
__version__='$Revision: 1.7 $'[11:-2]
from DocumentTemplate import *
import sys
......@@ -100,6 +100,7 @@ def test1():
ss=String(
"""\
%(comment)[ blah %(comment)]
<html><head><title>Test of documentation templates</title></head>
<body>
%(if args)[
......@@ -432,7 +433,7 @@ def test10():
html=HTML(
"""
<!--#var spam fmt="$%.2f bob's your uncle" null="spam%eggs!|"-->
""")
""") #'
print html(spam=42)
print html(spam=None)
#print html(spam=Missing.Value)
......@@ -501,6 +502,26 @@ def test13():
<!--#var expr="_.render(i.y)"-->,
<!--#var expr="_.render(i.h2)"-->""")(i=C())
def test14():
# test with tag
class person:
name='Jim'
height_inches=73
print HTML("""<!--#with person-->
Hi, my name is <!--#var name-->
My height is <!--#var "height_inches*2.54"--> centimeters.
<!--#/with-->""")(person=person)
def test15():
# test raise tag
try:
print HTML("""<!--#raise IndexError-->
The raise tag test suceeded!
<!--#/raise-->""")()
except IndexError, v:
print v
def main():
import traceback
print 'Test 1', '='*60
......@@ -533,6 +554,12 @@ def main():
print 'Test 11', '='*60
try: test11()
except: traceback.print_exc()
print 'Test 14', '='*60
try: test14()
except: traceback.print_exc()
print 'Test 15', '='*60
try: test15()
except: traceback.print_exc()
if __name__ == "__main__":
......@@ -542,6 +569,9 @@ if __name__ == "__main__":
############################################################################
# $Log: DTtest.py,v $
# Revision 1.7 1998/09/02 21:06:06 jim
# many changes for thread safety, bug fixes, and faster import
#
# Revision 1.6 1998/09/02 14:35:55 jim
# open source copyright
#
......
......@@ -51,23 +51,123 @@
# (540) 371-6909
#
##############################################################################
'''Document templates with fill-in fields
import DT_Doc, DT_Var, DT_In, DT_If, DT_Util, DT_Comment, DT_Raise, DT_With
__doc__=DT_Doc.__doc__ % {
'In': DT_In.__doc__,
'If': DT_If.__doc__,
'Var': DT_Var.__doc__,
'Expr': DT_Util.Expr_doc,
'Comment': DT_Comment.__doc__,
'Raise': DT_Raise.__doc__,
'With': DT_With.__doc__,
'id': '$Id: DocumentTemplate.py,v 1.6 1998/09/02 14:35:56 jim Exp $'
}
__version__='$Revision: 1.6 $'[11:-2]
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.
Addational control may be provided by providing document templates
with a 'validate' method. This would typically be done by
subclassing one or more of the DocumentTemplate classes.
If provided, the the 'validate' method will be called when objects
are accessed as accessed as instance attributes or when they are
accessed through keyed access in an expression.. The 'validate'
method will be called with five arguments:
1. The containing object that the object was accessed from,
2. The actual containing object that the object was found in,
which may be different from the containing onject the object
was accessed from, if the containing object supports
acquisition,
3. The name used to acces the object,
4. The object, and
5. The namespace object used to render the document template.
If a document template was called from Bobo, then the namespace
object will have an attribute, AUTHENTICATED_USER that is the
user object that was found if and when Bobo authenticated a user.
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.7 $'[11:-2]
ParseError='Document Template Parse Error'
from DT_String import String, File
from DT_HTML import HTML, HTMLFile, HTMLDefault
import DT_UI # Install HTML editing
from DT_Var import html_quote
# import DT_UI # Install HTML editing
from DT_Util import html_quote
......@@ -54,11 +54,12 @@
"""Very Safe Python Expressions
"""
__rcs_id__='$Id: VSEval.py,v 1.15 1998/09/02 14:35:56 jim Exp $'
__version__='$Revision: 1.15 $'[11:-2]
__rcs_id__='$Id: VSEval.py,v 1.16 1998/09/02 21:06:07 jim Exp $'
__version__='$Revision: 1.16 $'[11:-2]
from string import join, find, split, translate
import sys, gparse, string
import string
gparse=None
nltosp=string.maketrans('\r\n',' ')
......@@ -116,7 +117,9 @@ class Eval:
globals -- A global namespace.
"""
global gparse
if gparse is None: import gparse
self.__name__=expr
expr=translate(expr,nltosp)
self.expr=expr
......
......@@ -56,25 +56,16 @@ __doc__='''Package wrapper for Document Template
This wrapper allows the (now many) document template modules to be
segregated in a separate package.
$Id: __init__.py,v 1.7 1998/09/02 14:35:56 jim Exp $'''
__version__='$Revision: 1.7 $'[11:-2]
$Id: __init__.py,v 1.8 1998/09/02 21:06:07 jim Exp $'''
__version__='$Revision: 1.8 $'[11:-2]
import sys, string
import DocumentTemplate
String=DocumentTemplate.String
File=DocumentTemplate.File
HTML=DocumentTemplate.HTML
HTMLDefault=DocumentTemplate.HTMLDefault
HTMLFile=DocumentTemplate.HTMLFile
html_quote=DocumentTemplate.html_quote
from DocumentTemplate import String, File, HTMLDefault, HTMLFile, html_quote
try:
__.String=DocumentTemplate.String
__.File=DocumentTemplate.File
__.HTML=DocumentTemplate.HTML
__.HTMLDefault=DocumentTemplate.HTMLDefault
__.HTMLFile=DocumentTemplate.HTMLFile
__.html_quote=DocumentTemplate.html_quote
__.String=String
__.File=File
__.HTML=HTML
__.HTMLDefault=HTMLDefault
__.HTMLFile=HTMLFile
__.html_quote=html_quote
except: pass
......@@ -54,10 +54,10 @@
__doc__='''Python implementations of document template some features
$Id: pDocumentTemplate.py,v 1.15 1998/09/02 14:35:58 jim Exp $'''
__version__='$Revision: 1.15 $'[11:-2]
$Id: pDocumentTemplate.py,v 1.16 1998/09/02 21:06:07 jim Exp $'''
__version__='$Revision: 1.16 $'[11:-2]
import string, sys
import string, sys, types
from string import join
StringType=type('')
......
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