summaryrefslogtreecommitdiff
path: root/docs/devel_guide_src/pyModules.tex
blob: 2aa3236409db70844beb186c2b022814bd5a0f0c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
\section{.py Template Modules}
\label{pyModules}

This chapter examines the structure of a .py template module.  The following
few chapters will then show how each placeholder and directive affects the
generated Python code.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{An example}
\label{pyModules.example}

Our first template follows a long noble tradition in computer tutorials.
It produces a familiar, friendly greeting.  Here's the template:

\begin{verbatim}
Hello, world!
\end{verbatim}

... the output:

\begin{verbatim}
Hello, world!
\end{verbatim}

... and the .py template module cheetah-compile produced, with line
numbers added:

% @@MO: Is it possible to print the line numbers gray instead of black?

\begin{verbatim}
  1	#!/usr/bin/env python
    
  2	"""
  3	Autogenerated by CHEETAH: The Python-Powered Template Engine
  4	 CHEETAH VERSION: 0.9.12
  5	 Generation time: Sat Apr 20 14:27:47 2002
  6	   Source file: x.tmpl
  7	   Source file last modified: Wed Apr 17 22:10:59 2002
  8	"""
    
  9	__CHEETAH_genTime__ = 'Sat Apr 20 14:27:47 2002'
 10	__CHEETAH_src__ = 'x.tmpl'
 11	__CHEETAH_version__ = '0.9.12'
    
 12	##################################################
 13	## DEPENDENCIES
    
 14	import sys
 15	import os
 16	import os.path
 17	from os.path import getmtime, exists
 18	import time
 19	import types
 20	from Cheetah.Template import Template
 21	from Cheetah.DummyTransaction import DummyTransaction
 22	from Cheetah.NameMapper import NotFound, valueForName, 
           valueFromSearchList
 23	import Cheetah.Filters as Filters
 24	import Cheetah.ErrorCatchers as ErrorCatchers
    
 25	##################################################
 26	## MODULE CONSTANTS
    
 27	try:
 28	    True, False
 29	except NameError:
 30	    True, False = (1==1), (1==0)
    
 31	##################################################
 32	## CLASSES
    
 33	class x(Template):
 34	    """
 35	    
 36	    Autogenerated by CHEETAH: The Python-Powered Template Engine
 37	    """
\end{verbatim}
\begin{verbatim}
 38	    ##################################################
 39	    ## GENERATED METHODS
    
    
 40	    def __init__(self, *args, **KWs):
 41	        """
 42	        
 43	        """
    
 44	        Template.__init__(self, *args, **KWs)
 45	        self._filePath = 'x.tmpl'
 46	        self._fileMtime = 1019106659
    
 47	    def respond(self,
 48	            trans=None,
 49	            dummyTrans=False,
 50	            VFS=valueFromSearchList,
 51	            VFN=valueForName,
 52	            getmtime=getmtime,
 53	            currentTime=time.time):
    
    
 54	        """
 55	        This is the main method generated by Cheetah
 56	        """
    
 57	        if not trans:
 58	            trans = DummyTransaction()
 59	            dummyTrans = True
 60	        write = trans.response().write
 61	        SL = self._searchList
 62	        filter = self._currentFilter
 63	        globalSetVars = self._globalSetVars
 64	        
 65	        ########################################
 66	        ## START - generated method body
 67	        
 68	        if exists(self._filePath) and getmtime(self._filePath) > \
                    self._fileMtime:
 69	            self.compile(file=self._filePath)
 70	            write(getattr(self, self._mainCheetahMethod_for_x)
                        (trans=trans))
 71	            if dummyTrans:
 72	                return trans.response().getvalue()
 73	            else:
 74	                return ""
 75	        write('Hello, world!\n')
 76	        
 77	        ########################################
 78	        ## END - generated method body
 79	        
 80	        if dummyTrans:
 81	            return trans.response().getvalue()
 82	        else:
 83	            return ""
\end{verbatim}
\begin{verbatim}
 84	        
 85	    ##################################################
 86	    ## GENERATED ATTRIBUTES
    
    
 87	    __str__ = respond
    
 88	    _mainCheetahMethod_for_x= 'respond'
    
    
 89	# CHEETAH was developed by Tavis Rudd, Chuck Esterbrook, Ian Bicking 
        #     and Mike Orr;
 90	# with code, advice and input from many other volunteers.
 91	# For more information visit http://www.CheetahTemplate.org
    
 92	##################################################
 93	## if run from command line:
 94	if __name__ == '__main__':
 95	    x().runAsMainProgram()
    
\end{verbatim}

(I added the line numbers for this Guide, and split a few lines to fit the
page width.  The continuation lines don't have line numbers, and I added
indentation, backslashes and '\#' as necessary to make the result a valid
Python program.)

The examples were generated from CVS versions of Cheetah between 0.9.12 and
0.9.14.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{A walk through the example}
\label{pyModules.walk}

Lines 20-24 are the Cheetah-specific imports.  Line 33 introduces our generated
class, \code{x}, a subclass of \code{Template}.  It's called x because the
source file was x.tmpl.

Lines 40-46 are the \code{.\_\_init\_\_} method called when the template is
instantiated or used as a Webware servlet, or when the module is run as a
standalone program.  We can see it calling its superclass constructor and
setting \code{.\_filePath} and \code{.\_fileMtime} to the filename and
modification time (in Unix ticks) of the source .tmpl file.

Lines 47-84 are the main method \code{.respond}, the one that fills the
template.  Normally you call it without arguments, but Webware calls it with a
Webware \code{Transaction} object representing the current request.  Lines
57-59 set up the \code{trans} variable.  If a real or dummy transaction is
passed in, the method uses it.  Otherwise (if the \code{trans} argument is
\code{None}), the method creates a \code{DummyTransaction} instance.
\code{dummyTrans} is a flag that just tells whether a dummy transaction is in
effect; it'll be used at the end of the method.  

The other four \code{.respond} arguments aren't anything you'd ever want to
pass in; they exist solely to speed up access to these frequently-used
global functions.  This is a standard Python trick described in question 4.7
of the Python FAQ (\url{http://www.python.org/cgi-bin/faqw.py}).
\code{VFS} and \code{VFN} are the functions that give your template the
benefits of NameMapper lookup, such as the ability to use the searchList.  

Line 60 initializes the \code{write} variable.  This important variable is
discussed below.  

Lines 60-63 initialize a few more local variables.  \code{SL} is the 
searchList.  \code{filter} is the current output filter.  \code{globalSetVars}
are the variables that have been defined with \code{\#set global}.

The comments at lines 65 and 78 delimit the start and end of the code that
varies with each template.  The code outside this region is identical in all
template modules.  That's not quite true -- \code{\#import} for instance
generates additional \code{import} statements at the top of the module --
but it's true enough for the most part.

Lines 68-74 exist only if the template source was a named file rather than
a string or file object.  The stanza recompiles the template if the source
file has changed.  Lines 70-74 seem to be redundant with 75-83: both 
fill the template and send the output.  The reason the first set of lines
exists is because the second set may become invalid when the template is
recompiled.  (This is for {\em re}\ compilation only.  The initial compilation
happened in the \code{.\_\_init\_\_} method if the template wasn't 
precompiled.)

Line 75 is the most interesting line in this module.  It's a direct
translation of what we put in the template definition, ``Hello, world!'' Here
the content is a single string literal.  \code{write} looks like an ordinary
function call, but remember that line 60 made it an alias to
\code{trans.response().write}, a method in the transaction.  The next few
chapters describe how the different placeholders and directives influence this
portion of the generated class.

Lines 80-83 finish the template filling.  If \code{trans} is a real Webware
transaction, \code{write} has already sent the output to Webware for handling,
so we return \code{""}.  If \code{trans} is a dummy transaction, 
\code{write} has been accumulating the output in a Python \code{StringIO}
object rather than sending it anywhere, so we have to return it.

Line 83 is the end of the \code{.respond} method.

Line 87 makes code{.\_\_str\_\_} an alias for the main method, so that you
can \code{print} it or apply \code{str} to it and it will fill the template.
Line 88 gives the name of the main method, because sometimes it's not
\code{.respond}.  

Lines 94-95 allow the module to be run directly as a script.  Essentially,
they process the command-line arguments and them make the template fill
itself.


% Local Variables:
% TeX-master: "devel_guide"
% End: