DTML is the Document Template Markup Language, a handy presentation and templating language that comes with Zope. This Appendix is a reference to all of DTMLs markup tags and how they work.
The call
tag lets you call a method without inserting the results
into the DTML output.
call
tag syntax:
<dtml-call Variable|expr="Expression">
If the call tag uses a variable, the methods arguments are passed
automatically by DTML just as with the var
tag. If the method is
specified in a expression, then you must pass the arguments yourself.
Calling by variable name:
<dtml-call UpdateInfo>
This calls the UpdateInfo
object automatically passing arguments.
Calling by expression:
<dtml-call expr="RESPONSE.setHeader('content-type', 'text/plain')">
var tag
The comment tag lets you document your DTML with comments. You can also use it to temporarily disable DTML tags by commenting them out.
comment
tag syntax:
<dtml-comment> </dtml-comment>
The comment
tag is a block tag. The contents of the block are
not executed, nor are they inserted into the DTML output.
Documenting DTML:
<dtml-comment> This content is not executed and does not appear in the output. </dtml-comment>
Commenting out DTML:
<dtml-comment> This DTML is disabled and will not be executed. <dtml-call someMethod> </dtml-comment>
DTML utility functions provide some Python built-in functions and some DTML-specific functions.
chr(97)
returns the string a
. This is
the inverse of ord(). The argument must be in the range 0 to 255,
inclusive; ValueError
will be raised if the integer is outside
that range.DateTime
object given constructor
arguments. See the DateTime API reference for more
information on constructor arguments.(a / b, a % b)
. For floating point
numbers the result is (q, a % b)
, where q is usually
math.floor(a / b)
but may be 1 less than that. In any case 'q *
b + a % b' is very close to a, if a % b
is non-zero it has the
same sign as b, and 0 <= abs(a % b) < abs(b)
.string.atof(number)
. Otherwise, the argument may be a plain or
long integer or a floating point number, and a floating point
number with the same value (within Python's floating point
precision) is returned.getattr(x, "foobar")
is equivalent
to x.foobar
. If the named attribute does not exist, default is
returned if provided, otherwise AttributeError
is raised.render
is true, the variable is rendered. See the render
function.hex(-1)
yields 0xffffffff
. When evaluated on a machine with the same word
size, this literal is evaluated as -1; at a different word size, it
may turn up as a large positive number or raise an OverflowError
exception.radix
parameter gives the
base for the conversion and may be any integer in the range 2 to
36. If radix
is specified and the number is not a string,
TypeError
is raised. Otherwise, the argument may be a plain or
long integer or a floating point number. Conversion of floating
point numbers to integers is defined by the C semantics; normally
the conversion truncates towards zero.name=value
pairs are pushed into the new
namespace.oct(-1)
yields
037777777777
. When evaluated on a machine with the same word size,
this literal is evaluated as -1; at a different word size, it may
turn up as a large positive number or raise an OverflowError
exception.ord("a")
returns the integer 97. This is the
inverse of chr()
.pow(2, -1)
or pow(2, 35000)
is not
allowed.ValueError
is raised).object
. For DTML objects this
evaluates the DTML code with the current namespace. For other
objects, this is equivalent to str(object)
.with
and without the items mentioned in
without
. Items from s not mentioned in with are removed. s,
with, and without are all either sequences of strings or
sequences of key-value tuples, with ordering done on the
keys. This function is useful for constructing ordered select
lists.REQUEST.AUTHENTICATED_USER
object. However, the AUTHENTICATED_USER
object is insecure since
it can be replaced.object
is
the object the value was accessed in, parent
is the container of
the value, and name
is the named used to access the value (for
example, if it was obtained via 'getattr'). You may omit some of
the arguments, however it is best to provide all available
arguments.SecurityValidate(None, None, None, object)
.None
object is equivalent to the Python built-in object
None
. This is usually used to represent a Null or false value. string
module
random
module
math
module
sequence
module
The if
tags allows you to test conditions and to take different
actions depending on the conditions. The if
tag mirrors Python's
if/elif/else
condition testing statements.
If tag syntax:
<dtml-if ConditionVariable|expr="ConditionExpression"> [<dtml-elif ConditionVariable|expr="ConditionExpression">] ... [<dtml-else>] </dtml-if>
The if
tag is a block tag. The if
tag and optional elif
tags
take a condition variable name or a condition expression, but not
both. If the condition name or expression evaluates to true then
the if
block is executed. True means not zero, an empty string
or an empty list. If the condition variable is not found then the
condition is considered false.
If the initial condition is false, each elif
condition is tested
in turn. If any elif
condition is true, its block is
executed. Finally the optional else
block is executed if none of
the if
and elif
conditions were true. Only one block will be
executed.
Testing for a variable:
<dtml-if snake> The snake variable is true </dtml-if>
Testing for expression conditions:
<dtml-if expr="num > 5"> num is greater than five <dtml-elif expr="num < 5"> num is less than five <dtml-else> num must be five </dtml-if>
Python Tutorial: If Statements
The in
tag gives you powerful controls for looping over sequences
and performing batch processing.
in
tag syntax:
<dtml-in SequenceVariable|expr="SequenceExpression"> [<dtml-else>] </dtml-in>
The in
block is repeated once for each item in the sequence
variable or sequence expression. The current item is pushed on to
the DTML namespace during each executing of the in
block.
If there are no items in the sequence variable or expression, the
optional else
block is executed.
For example, if the sequence size is 12, the batch size is 10 the orphan size is 3, then the result is one batch with all 12 items since splitting the items into two batches would result in a batch smaller than the orphan size.
The default value is 0.
These variables describe the current item.
(key,value)
, the in
tag interprets them as
(sequence-key, sequence-item)
. sequence-var-title
is the title
variable of the
current item. Normally you can access these variables directly
since the current item is pushed on the DTML namespace. However
these variables can be useful when displaying previous and next
batch information.These variable summarize information about numeric item variables. To use these variable you must loop over objects (like database query results) that have numeric variables.
These variables allow you to track changes in current item variables.
start
variable
removed. You can use this variable to construct links to next
and previous batches.previous-sequence-start-index
+ 1.previous-sequence-end-index
+ 1.batch-start-index
, batch-end-index
, and
batch-size
.next-sequence-start-index
+ 1.next-sequence-end-index
+ 1.batch-start-index
, batch-end-index
, and batch-size
.Looping over sub-objects:
<dtml-in objectValues> 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> id: <dtml-var sequence-key>, title: <dtml-var title><br> </dtml-in>
Creating alternate colored table cells:
<table> <dtml-in objectValues> <tr <dtml-if sequence-odd>bgcolor="#EEEEEE" <dtml-else>bgcolor="#FFFFFF" </dtml-if> <td><dtml-var title></td> </tr> </dtml-in> </table>
Basic batch processing:
<p> <dtml-in largeSequence size=10 start=start previous> <a href="<dtml-var absolute_url><dtml-var sequence-query>start=<dtml-var previous-sequence-start-number>">Previous</a> </dtml-in> <dtml-in largeSequence size=10 start=start next> <a href="<dtml-var absolute_url><dtml-var sequence-query>start=<dtml-var next-sequence-start-number>">Next</a> </dtml-in> </p> <p> <dtml-in largeSequence size=10 start=start> <dtml-var sequence-item> </dtml-in> </p>
This example creates Previous and Next links to navigate
between batches. Note, by using sequence-query
, you do not lose
any GET variables as you navigate between batches.
The let
tag defines variables in the DTML namespace.
let
tag syntax:
<dtml-let [Name=Variable][Name="Expression"]...> </dtml-let>
The let
tag is a block tag. Variables are defined by tag
arguments. Defined variables are pushed onto the DTML namespace
while the let
block is executed. Variables are defined by
attributes. The let
tag can have one or more attributes with
arbitrary names. If the attributes are defined with double quotes
they are considered expressions, otherwise they are looked up by
name. Attributes are processed in order, so later attributes can
reference, and/or overwrite earlier ones.
Basic usage:
<dtml-let name="'Bob'" ids=objectIds> name: <dtml-var name> ids: <dtml-var ids> </dtml-let>
Using the let
tag with the in
tag:
<dtml-in expr="(1,2,3,4)"> <dtml-let num=sequence-item index=sequence-index result="num*index"> <dtml-var num> * <dtml-var index> = <dtml-var result> </dtml-let> </dtml-in>
This yields:
1 * 0 = 0 2 * 1 = 2 3 * 2 = 6 4 * 3 = 12
with tag
The mime
tag allows you to create MIME encoded data. It is chiefly
used to format email inside the sendmail
tag.
mime
tag syntax:
<dtml-mime> [<dtml-boundry>] ... </dtml-mime>
The mime
tag is a block tag. The block is can be divided by one
or more boundry
tags to create a multi-part MIME message. mime
tags may be nested. The mime
tag is most often used inside the
sendmail
tag.
Both the mime
and boundry
tags
have the same attributes.
base64
. Valid encoding options include base64
,
quoted-printable
, uuencode
, x-uuencode
, uue
, x-uue
,
and 7bit
. If the encode
attribute is set to 7bit
no
encoding is done on the block and the data is assumed to be in a
valid MIME format.type
and type_expr
.name
and name_expr
.disposition
and
disposition_expr
.filename
and
filename_expr
.Sending a file attachment:
<dtml-sendmail> To: <dtml-recipient> Subject: Resume <dtml-mime type="text/plain" encode="7bit"> Hi, please take a look at my resume. <dtml-boundary type="application/octet-stream" disposition="attachment" encode="base64" filename_expr="resume_file.getId()"><dtml-var expr="resume_file.read()"></dtml-mime> </dtml-sendmail>
The raise
tag raises an exception, mirroring the Python raise
statement.
raise
tag syntax:
<dtml-raise ExceptionName|ExceptionExpression> </dtml-raise>
The raise
tag is a block tag. It raises an exception. Exceptions
can be an exception class or a string. The contents of the tag are
passed as the error value.
Raising a KeyError:
<dtml-raise KeyError></dtml-raise>
Raising an HTTP 404 error:
<dtml-raise NotFound>Web Page Not Found</dtml-raise>
try tag
Python Tutorial: Errors and Exceptions
The return
tag stops executing DTML and returns data. It mirrors
the Python return
statement.
return
tag syntax:
<dtml-return ReturnVariable|expr="ReturnExpression">
Stops execution of DTML and returns a variable or expression. The DTML output is not returned. Usually a return expression is more useful than a return variable. Scripts largely obsolete this tag.
Returning a variable:
<dtml-return result>
Returning a Python dictionary:
<dtml-return expr="{'hi':200, 'lo':5}">
The sendmail
tag sends an email message
using SMTP.
sendmail
tag syntax:
<dtml-sendmail> </dtml-sendmail>
The sendmail
tag is a block tag. It either requires a mailhost
or a smtphost
argument, but not both. The tag block is sent as
an email message. The beginning of the block describes the email
headers. The headers are separated from the body by a blank
line. Alternately the To
, From
and Subject
headers can be
set with tag arguments.
To
header.From
header.Subject
header.Sending an email message using a Mail Host:
<dtml-sendmail mailhost="mailhost"> To: <dtml-var recipient> From: <dtml-var sender> Subject: <dtml-var subject> Dear <dtml-var recipient>, You order number <dtml-var order_number> is ready. Please pick it up at your soonest convenience. </dtml-sendmail>
mime tag
The sqlgroup
tag formats complex boolean SQL expressions. You can
use it along with the sqltest
tag to build dynamic SQL queries
that tailor themselves to the environment. This tag is used in SQL
Methods.
sqlgroup
tag syntax:
<dtml-sqlgroup> [<dtml-or>] [<dtml-and>] ... </dtml-sqlgroup>
The sqlgroup
tag is a block tag. It is divided into blocks with
one or more optional or
and and
tags. sqlgroup
tags can be
nested to produce complex logic.
sqlgroup
tag in a SQL select
query.Sample usage:
select * from employees <dtml-sqlgroup where> <dtml-sqltest salary op="gt" type="float" optional> <dtml-and> <dtml-sqltest first type="nb" multiple optional> <dtml-and> <dtml-sqltest last type="nb" multiple optional> </dtml-sqlgroup>
If first
is Bob
and last
is Smith, McDonald
it renders:
select * from employees where (first='Bob' and last in ('Smith', 'McDonald') )
If salary
is 50000 and last
is Smith
it renders:
select * from employees where (salary > 50000.0 and last='Smith' )
Nested sqlgroup
tags:
select * from employees <dtml-sqlgroup where> <dtml-sqlgroup> <dtml-sqltest first op="like" type="nb"> <dtml-and> <dtml-sqltest last op="like" type="nb"> <dtml-sqlgroup> <dtml-or> <dtml-sqltest salary op="gt" type="float"> </dtml-sqlgroup>
Given sample arguments, this template renders to SQL like so:
select * form employees where ( ( name like 'A*' and last like 'Smith' ) or salary > 20000.0 )
sqltest tag
The sqltest
tag inserts a condition test into SQL code. It tests a
column against a variable. This tag is used in SQL Methods.
sqltest
tag syntax:
<dtml-sqltest Variable|expr="VariableExpression">
The sqltest
tag is a singleton. It inserts a SQL condition test
statement. It is used to build SQL queries. The sqltest
tag
correctly escapes the inserted variable. The named variable or
variable expression is tested against a SQL column using the
specified comparison operation.
string
, int
, float
and nb
. nb
means non-blank string,
and should be used instead of string
unless you want to test for
blank values. The type attribute is required and is used to
properly escape inserted variable. The comparison defaults to equal to. If the comparison is not
recognized it is used anyway. Thus you can use comparisons such
as like
.
Basic usage:
select * from employees where <dtml-sqltest name type="nb">
If the name
variable is Bob
then this renders:
select * from employees where name = 'Bob'
Multiple values:
select * from employees where <dtml-sqltest empid type=int multiple>
If the empid
variable is (12,14,17)
then this renders:
select * from employees where empid in (12, 14, 17)
sqlgroup tag
sqlvar tag
The sqlvar
tag safely inserts variables into SQL code. This tag is
used in SQL Methods.
sqlvar
tag syntax:
<dtml-sqlvar Variable|expr="VariableExpression">
The sqlvar
tag is a singleton. Like the var
tag, the sqlvar
tag looks up a variable and inserts it. Unlike the var tag, the
formatting options are tailored for SQL code.
string
, int
, float
and nb
. nb
means non-blank string and
should be used in place of string
unless you want to use blank
strings. The type attribute is required and is used to properly
escape inserted variable.Basic usage:
select * from employees where name=<dtml-sqlvar name type="nb">
This SQL quotes the name
string variable.
sqltest tag
The tree
tag displays a dynamic tree widget by querying Zope
objects.
tree
tag syntax:
<dtml-tree [VariableName|expr="VariableExpression"]> </dtml-tree>
The tree
tag is a block tag. It renders a dynamic tree widget in
HTML. The root of the tree is given by variable name or
expression, if present, otherwise it defaults to the current
object. The tree
block is rendered for each tree node, with the
current node pushed onto the DTML namespace.
Tree state is set in HTTP cookies. Thus for trees to work, cookies must be enabled. Also you can only have one tree per page.
tpValues
which most Zope objects
support. tpId
which most Zope objects support. This
attribute is for advanced usage only.tpURL
which most Zope objects
support. This attribute is for advanced usage only.<dtml-var standard_html_header>
and end with
<dtml-var standard_html_footer>
in order to ensure proper
display in the tree.tree-level
variable can
be used to calculate table rows and colspan settings when
inserting table rows into the tree table.You can control the tree tag by setting these variables.
Display a tree rooted in the current object:
<dtml-tree> <dtml-var title_or_id> </dtml-tree>
Display a tree rooted in another object, using a custom branches method:
<dtml-tree expr="folder.object" branches="objectValues"> Node id : <dtml-var getId> </dtml-tree>
The try
tag allows exception handling in DTML, mirroring the
Python try/except
and try/finally
constructs.
The try
tag has two different syntaxes, try/except/else
and
try/finally
.
try/except/else
Syntax:
<dtml-try> <dtml-except [ExceptionName] [ExceptionName]...> ... [<dtml-else>] </dtml-try>
The try
tag encloses a block in which exceptions can be caught and
handled. There can be one or more except
tags that handles
zero or more exceptions. If an except
tag does not specify an
exception, then it handles all exceptions.
When an exception is raised, control jumps to the first except
tag that handles the exception. If there is no except
tag to
handle the exception, then the exception is raised normally.
If no exception is raised, and there is an else
tag, then the
else
tag will be executed after the body of the try
tag.
The except
and else
tags are optional.
try/finally
Syntax:
<dtml-try> <dtml-finally> </dtml-try>
The finally
tag cannot be used in the same try
block as the
except
and else
tags. If there is a finally
tag, its block
will be executed whether or not an exception is raised in the
try
block.
Inside the except
block these variables
are defined.
Catching a math error:
<dtml-try> <dtml-var expr="1/0"> <dtml-except ZeroDivisionError> You tried to divide by zero. </dtml-try>
Returning information about the handled exception:
<dtml-try> <dtml-call dangerousMethod> <dtml-except> An error occurred. Error type: <dtml-var error_type> Error value: <dtml-var error_value> </dtml-try>
Using finally to make sure to perform clean up regardless of whether an error is raised or not:
<dtml-call acquireLock> <dtml-try> <dtml-call someMethod> <dtml-finally> <dtml-call releaseLock> </dtml-try>
raise tag
Python Tutorial: Errors and Exceptions
The unless
tag provides a shortcut for testing negative
conditions. For more complete condition testing use the if
tag.
unless
tag syntax:
<dtml-unless ConditionVariable|expr="ConditionExpression"> </dtml-unless>
The unless
tag is a block tag. If the condition variable or
expression evaluates to false, then the contained block is
executed. Like the if
tag, variables that are not present are
considered false.
Testing a variable:
<dtml-unless testMode> <dtml-call dangerousOperation> </dtml-unless>
The block will be executed if testMode
does not exist, or exists
but is false.
if tag
The var
tags allows you insert variables into
DTML output.
var
tag syntax:
<dtml-var Variable|expr="Expression">
The var
tag is a singleton tag. The var
tag finds a variable
by searching the DTML namespace which usually consists of current
object, the current object's containers, and finally the web
request. If the variable is found, it is inserted into the DTML
output. If not found, Zope raises an error.
var
tag entity syntax:
&dtml-variableName;
Entity syntax is a short cut which inserts and HTML quotes the variable. It is useful when inserting variables into HTML tags.
var
tag entity syntax with attributes:
&dtml.attribute1[.attribute2]...-variableName;
To a limited degree you may specify attributes with the entity
syntax. You may include zero or more attributes delimited by
periods. You cannot provide arguments for attributes using the
entity syntax. If you provide zero or more attributes, then the
variable is not automatically HTML quoted. Thus you can avoid HTML
quoting with this syntax, &dtml.-variableName;
.
12000
becomes 12,000
.absolute_url
method.url_quote
but also
converts spaces to plus signs.size
attribute listed
above). By default, this is ...
Inserting a simple variable into a document:
<dtml-var standard_html_header>
Truncation:
<dtml-var colors size=10 etc=", etc.">
will produce the following output if colors is the string 'red yellow green':
red yellow, etc.
C-style string formatting:
<dtml-var expr="23432.2323" fmt="%.2f">
renders to:
23432.23
Inserting a variable, link, inside an HTML A
tag with the entity
syntax:
<a href="&dtml-link;">Link</a>
Inserting a link to a document doc
, using entity syntax with
attributes:
<a href="&dtml.url-doc;"><dtml-var doc fmt="title_or_id"></a>
This creates an HTML link to an object using its URL and
title. This example calls the object's absolute_url
method for
the URL (using the url
attribute) and its title_or_id
method
for the title.
The with
tag pushes an object onto the DTML namespace. Variables
will be looked up in the pushed object first.
with
tag syntax:
<dtml-with Variable|expr="Expression"> </dtml-with>
The with
tag is a block tag. It pushes the named variable or
variable expression onto the DTML namespace for the duration of
the with
block. Thus names are looked up in the pushed object
first.
with
tag.Looking up a variable in the REQUEST:
<dtml-with REQUEST only> <dtml-if id> <dtml-var id> <dtml-else> 'id' was not in the request. </dtml-if> </dtml-with>
Pushing the first child on the DTML namespace:
<dtml-with expr="objectValues()[0]"> First child's id: <dtml-var id> </dtml-with>
let tag