summaryrefslogtreecommitdiff
path: root/docs/users_guide_2_src/08_inheritanceEtc.txt
blob: 3e76ce228e3401dfb9cba9d12e19c352d654255c (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
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Import, Inheritance, Declaration and Assignment}
\label{inheritanceEtc}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{\#import and \#from directives}
\label{inheritanceEtc.import}

Syntax:
\begin{verbatim}
#import MODULE_OR_OBJECT [as NAME] [, ...]
#from MODULE import MODULE_OR_OBJECT [as NAME] [, ...]
\end{verbatim}


The \code{\#import} and \code{\#from} directives are used to make external
Python modules or objects available to placeholders.  The syntax is identical
to the import syntax in Python.  Imported modules are visible globally to all
methods in the generated Python class.

\begin{verbatim}
#import math
#import math as mathModule
#from math import sin, cos
#from math import sin as _sin
#import random, re
#from mx import DateTime         # ## Part of Egenix's mx package.
\end{verbatim}

After the above imports, \code{\$math}, \code{\$mathModule}, 
\code{\$sin}, \code{\$cos} and \code{\$\_sin}, \code{\$random}, \code{\$re} 
and \code{\$DateTime} may be used in \code{\$placeholders} and expressions.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{\#extends}
\label{inheritanceEtc.extends}

Syntax:
\begin{verbatim}
#extends CLASS
\end{verbatim}


All templates are subclasses of \code{Cheetah.Template.Template}.  However,
it's possible for a template to subclass another template or a pure Python
class.  This is where \code{\#extends} steps in: it
specifies the parent class.  It's equivalent to PSP's \code{``@page extends=''}
directive. 

Cheetah imports the class mentioned in an \code{\#extends} directive
automatically if you haven't imported it yet.  The implicit importing works
like this:

\begin{verbatim}
#extends Superclass   
## Implicitly does '#from Superclass import Superclass'.

#extends Cheetah.Templates.SkeletonPage
## Implicitly does '#from Cheetah.Templates.SkeletonPage import SkeletonPage'.
\end{verbatim}

If your superclass is in an unusual location or in a module named 
differently than the class, you must import it explicitly.  There is no
support for extending from a class that is not imported; e.g., from a template
dynamically created from a string.  Since the most practical way to
get a parent template into a module is to precompile it, all parent templates
essentially have to be precompiled.  

There can be only one \code{\#extends} directive in a template and it
may list only one class.  In other words, templates don't do multiple
inheritance.  This is intentional: it's too hard to initialize multiple
base classes correctly from inside a template.  However, you can do
multiple inheritance in your pure Python classes.

If your pure Python class overrides any of the standard \code{Template}
methods such as \code{.\_\_init\_\_} or \code{.awake}, be sure to call
the superclass method in your method or things will break.  Examples of calling
the superclass method are in section \ref{tips.callingSuperclassMethods}.
A list of all superclass methods is in section 
\ref{tips.allMethods}.

In all cases, the root superclass must be \code{Template}.  If your
bottommost class is a template, simply omit the \code{\#extends} in it and it
will automatically inherit from \code{Template}.  {\em If your bottommost class
is a pure Python class, it must inherit from \code{Template} explicitly: }
\begin{verbatim}
from Cheetah.Template import Template
class MyPurePythonClass(Template):
\end{verbatim}

If you're not keen about having your Python classes inherit from
\code{Template}, create a tiny glue class that inherits both from your
class and from \code{Template}.

Before giving any examples we'll stress that Cheetah does {\em not}
dictate how you should structure your inheritance tree.  As long as
you follow the rules above, many structures are possible.

Here's an example for a large web site that has not only a general site
template, but also a template for this section of the site, and then a
specific template-servlet for each URL.  (This is the ``inheritance
approach'' discussed in the Webware chapter.)  Each template inherits from a
pure Python class that contains methods/attributes used by the template.  We'll
begin with the bottommost superclass and end with the specific
template-servlet:

\begin{verbatim}
1.  SiteLogic.py (pure Python class containing methods for the site)
        from Cheetah.Template import Template
        class SiteLogic(Template):

2.  Site.tmpl/py  (template containing the general site framework;
                   this is the template that controls the output,
                   the one that contains "<HTML><HEAD>...", the one
                   that contains text outside any #def/#block.)
        #from SiteLogic import SiteLogic
        #extends SiteLogic
        #implements respond

3.  SectionLogic.py  (pure Python class with helper code for the section)
        from Site import Site
        class SectionLogic(Site)

4.  Section.tmpl/py  (template with '#def' overrides etc. for the section)
        #from SectionLogic import SectionLogic
        #extends SectionLogic

5.  page1Logic.py  (pure Python class with helper code for the template-servlet)
        from Section import Section
        class indexLogic(Section):

6.  page1.tmpl/py  (template-servlet for a certain page on the site)
        #from page1Logic import page1Logic
        #extends page1Logic
\end{verbatim}

A pure Python classes might also contain methods/attributes that aren't used by
their immediate child template, but are available for any descendant
template to use if it wishes.  For instance, the site template might have
attributes for the name and e-mail address of the site administrator, 
ready to use as \$placeholders in any template that wants it.

{\em Whenever you use \code{\#extends}, you often need \code{\#implements}
too,} as in step 2 above.  Read the next section to understand what
\code{\#implements} is and when to use it.

% @@MO: Edmund suggests making some diagrams of inheritance chains.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{\#implements}
\label{inheritanceEtc.implements}

Syntax:
\begin{verbatim}
#implements METHOD
\end{verbatim}

You can call any \code{\#def} or \code{\#block} method directly and get its
outpt.  The top-level content -- all the text/placeholders/directives outside any
\code{\#def}/\code{\#block} -- gets concatenated and wrapped in a ``main
method'', by default \code{.respond()}.  So if you call \code{.respond()}, you
get the ``whole template output''.  When Webware calls \code{.respond()},
that's what it's doing.  And when you do 'print t' or 'str(t)' on a template
instance, you're taking advantage of the fact that Cheetah makes
\code{.\_\_str\_\_()} an alias for the main method.

That's all fine and dandy, but what if your application prefers to call another
method name rather than \code{.respond()}?  What if it wants to call, say,
\code{.send\_output()} instead?  That's where \code{\#implements} steps in.  It
lets you choose the name for the main method.  Just put this in your template
definition:
\begin{verbatim}
#implements send_output
\end{verbatim}

When one template extends another, every template in the inheritance chain
has its own main method.  To fill the template, you invoke exactly one of
these methods and the others are ignored.  The method you call may be in any of
the templates in the inheritance chain: the base template, the leaf template,
or any in between, depending on how you structure your application.  So you
have two problems: (1) calling the right method name, and (2) preventing an
undesired same-name subclass method from overriding the one you want to call.  

Cheetah assumes the method you will call is \code{.respond()} because
that's what Webware calls.  It further assumes the desired main method is the
one in the lowest-level base template, because that works well with
\code{\#block} as described in the Inheritance Approach for building Webware
servlets (section \ref{webware.inheritance}), which was originally the
principal use for Cheetah.  So when you use \code{\#extends}, Cheetah changes
that template's main method to \code{.writeBody()} to get it out of the way and
prevent it from overriding the base template's \code{.respond()}.  

Unfortunately this assumption breaks down if the template is used in other
ways.  For instance, you may want to use the main method in the highest-level
leaf template, and treat the base template(s) as merely a library of
methods/attributes.  In that case, the leaf template needs \code{\#implements
respond} to change its main method name back to \code{.respond()} (or whatever
your application desires to call).  Likewise, if your main method is in one of the
intermediate templates in an inheritance chain, that template needs
\code{\#implements respond}.

The other way the assumption breaks down is if the main method {\em is} in
the base template but that template extends a pure Python class.  Cheetah sees
the \code{\#extends} and dutifully but incorrectly renames the method to
\code{.writeBody()}, so you have to use \code{\#implements respond} to change
it back.  Otherwise the dummy \code{.respond()} in \code{Cheetah.Template}
is found, which outputs...  nothing.  {\bf So if you're using \code{\#extends}
and get no output, the {\em first} thing you should think is, ``Do I need to
add \code{\#implements respond} somewhere?'' }




%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{\#set}
\label{inheritanceEtc.set}

Syntax:
\begin{verbatim}
#set [global] $var = EXPR
\end{verbatim}

\code{\#set} is used to create and update local variables at run time.
The expression may be any Python expression.
Remember to preface variable names with \$ unless they're part of an
intermediate result in a list comprehension.

Here are some examples:
\begin{verbatim}
#set $size = $length * 1096
#set $buffer = $size + 1096
#set $area = $length * $width
#set $namesList = ['Moe','Larry','Curly']
#set $prettyCountry = $country.replace(' ', '&nbsp;')
\end{verbatim}

\code{\#set} variables are useful to assign a short name to a
\code{\$deeply.nested.value}, to a calculation, or to a printable version of
a value.  The last example above converts any spaces in the 'country' value
into HTML non-breakable-space entities, to ensure the entire value appears on
one line in the browser.

\code{\#set} variables are also useful in \code{\#if} expressions, but
remember that complex logical routines should be coded in Python, not in
Cheetah!
\begin{verbatim}
#if $size > 1500
  #set $adj = 'large'
#else
  #set $adj = 'small'
#end if
\end{verbatim}
Or Python's one-line equivalent, "A and B or C".  Remember that in this case,
B must be a true value (not None, '', 0, [] or {}).  
\begin{verbatim}
#set $adj = $size > 1500 and 'large' or 'small'
\end{verbatim}
(Note: Cheetah's one-line \code{\#if} will not work for this, since it
produces output rather than setting a variable.

You can also use the augmented assignment operators:
\begin{verbatim}
## Increment $a by 5.
#set $a += 5      
\end{verbatim}

By default, \code{\#set} variables are not visible in method calls or include
files unless you use the \code{global} attribute: \code{\#set global \$var =
EXPRESSION}.  Global variables are visible in all methods, nested templates and
included files.  Use this feature with care to prevent surprises.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{\#del}
\label{inheritanceEtc.del}

Syntax:
\begin{verbatim}
#del $var
\end{verbatim}

\code{\#del} is the opposite of \code{\#set}.  It deletes a {\em local}
variable.  Its usage is just like Python's \code{del} statement:
\begin{verbatim}
#del $myVar
#del $myVar, $myArray[5]
\end{verbatim}

Only local variables can be deleted.  There is no directive to delete a
\code{\#set global} variable, a searchList variable, or any other type of
variable.  

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{\#attr}
\label{inheritanceEtc.attr}

Syntax:
\begin{verbatim}
#attr $var = EXPR
\end{verbatim}

The \code{\#attr} directive creates class attributes in the generated Python
class.  It should be used to assign simple Python literals such as numbers or
strings.  In particular, the expression must {\em not} depend on searchList
values or \code{\#set} variables since those are not known at compile time.

\begin{verbatim}
#attr $title = "Rob Roy"
#attr $author = "Sir Walter Scott"
#attr $version = 123.4
\end{verbatim}

This template or any child template can output the value thus:
\begin{verbatim}
$title, by $author, version $version
\end{verbatim}

If you have a library of templates derived from etexts
(\url{http://www.gutenberg.org/}), you can extract the titles and authors
and put them in a database (assuming the templates have been compiled into
.py template modules):

%\begin{verbatim}
%import glob
%
%\end{verbatim}
%
% @@MO: Finish this example.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{\#def}
\label{inheritanceEtc.def}

Syntax:
\begin{verbatim}
#def METHOD[(ARGUMENTS)]
#end def
\end{verbatim}

Or the one-line variation:
\begin{verbatim}
#def METHOD[(ARGUMENTS)] : TEXT_AND_PLACEHOLDERS
\end{verbatim}


The \code{\#def} directive is used to define new methods in the generated
Python class, or to override superclass methods.  It is analogous to Python's
\code{def} statement.  The directive is silent, meaning it does not itself
produce any output.  However, the content of the method will be inserted into
the output (and the directives executed) whenever the method is later called by
a \$placeholder.

\begin{verbatim}
#def myMeth()
This is the text in my method 
$a $b $c(123)  ## these placeholder names have been defined elsewhere
#end def

## and now use it...
$myMeth()
\end{verbatim}

The arglist and parentheses can be omitted:
\begin{verbatim}
#def myMeth
This is the text in my method 
$a $b $c(123)
#end def

## and now use it...
$myMeth
\end{verbatim}

Methods can have arguments and have defaults for those arguments, just like
in Python.  Remember the \code{\$} before variable names:
\begin{verbatim}
#def myMeth($a, $b=1234)
This is the text in my method 
$a - $b
#end def

## and now use it...
$myMeth(1)
\end{verbatim}

The output from this last example will be:

\begin{verbatim}
This is the text in my method 
1 - 1234
\end{verbatim}

There is also a single line version of the \code{\#def} directive.  
{\bf Unlike the multi-line directives, it uses a colon (:) to delimit the method
signature and body}:
\begin{verbatim}
#attr $adj = 'trivial'
#def myMeth: This is the $adj method 
$myMeth
\end{verbatim}
Leading and trailing whitespace is stripped from the method.  This is in
contrast to:
\begin{verbatim}
#def myMeth2
This is the $adj method
#end def
\end{verbatim}
where the method includes a newline after "method".  If you don't want the
newline, add \code{\#slurp}:
\begin{verbatim}
#def myMeth3
This is the $adj method#slurp
#end def
\end{verbatim}

Because \code{\#def} is handled at compile time, it can appear above or
below the placeholders that call it.  And if a superclass placeholder
calls a method that's overridden in a subclass, it's the subclass method
that will be called.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{\#block ... \#end block}
\label{inheritanceEtc.block}


The \code{\#block} directive allows you to mark a section of your template that
can be selectively reimplemented in a subclass.  It is very useful for
changing part of a template without having to copy-paste-and-edit
the entire thing.  The output from a template definition that uses blocks will
be identical to the output from the same template with the \code{\#block \ldots
\#end block} tags removed. 

({\em Note:} don't be confused by the generic word `block'' in this Guide,
which means a section of code inside {\em any} \code{\#TAG \ldots \#end TAG}
pair.  Thus, an if-block, for-block, def-block, block-block etc.  In this
section we are talking only of block-blocks.)

To reimplement the block, use the \code{\#def} directive.  The magical effect
is that it appears to go back and change the output text {\em at the point the
original block was defined} rather than at the location of the
reimplementation.

\begin{verbatim}
#block testBlock
Text in the contents 
area of the block directive
#if $testIt
$getFoo() 
#end if
#end block testBlock
\end{verbatim}

You can repeat the block name in the \code{\#end block} directive or not, as
you wish.

\code{\#block} directives can be nested to any depth.

\begin{verbatim}
#block outerBlock
Outer block contents 

#block innerBlock1
inner block1 contents 
#end block innerBlock1

#block innerBlock2
inner block2 contents 
#end block innerBlock2

#end block outerBlock
\end{verbatim}

Note that the name of the block is optional for the \code{\#end block} tag.

Technically, \code{\#block} directive is equivalent to a \code{\#def} directive
followed immediately by a \code{\#placeholder} for the same name.  In fact,
that's what Cheetah does.  Which means you can use \code{\$theBlockName}
elsewhere in the template to output the block content again.

There is a one-line \code{\#block} syntax analagous to the one-line 
\code{\#def}.  

The block must not require arguments because the implicit placeholder that's
generated will call the block without arguments.


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


Object-Oriented Documents
-------------------------

..
    :label: howWorks.objoriented

Because Cheetah documents are actually class definitions, templates may inherit
from one another in a natural way, using regular Python semantics. For
instance, consider this template, FrogBase.tmpl::

    #def title
    This document has not defined its title
    #end def
    #def htTitle
    $title
    #end def
    <HTML><HEAD>
    <TITLE>$title</TITLE>
    </HEAD><BODY>
    <H1>$htTitle</H1>
    $body
    </BODY></HTML>

And its subclassed document, Frog1.tmpl::

    #from FrogBase import FrogBase
    #extends FrogBase
    #def title
    The Frog Page
    #end def
    #def htTitle
    The <IMG SRC="Frog.png"> page
    #end def
    #def body
    ... lots of info about frogs ...
    #end def


This is a classic use of inheritance. The parent "template" is simply an
abstract superclass.  Each document specializes the output of its parent.
For instance, here the parent defines
``\$htTitle`` so that by default it's identical to whatever the 
``\$title`` is, but it can also be customized.  

In many other templating systems, you'd have to use case statements or
if-elseif blocks of some sort, repeated in many different sections of code.

While we show another Cheetah document inheriting from this parent, a Python
class can inherit from it just as easily. This Python class could define its
programmatically-driven value for ``\$body`` and ``\$title``, simply by
defining body() and title() methods that return a string.  (Actually they
can return anything, but we'll get into that later.)  ::

    from FrogBase import FrogBase
    class Frog2(FrogBase):
        def title(self):
            return "Frog 2 Page"
        # We don't override .htTitle, so it defaults to "Frog 2 Page" too.
        def body(self):
            return " ... more info about frogs ..."

Similarly, the Cheetah document can inherit from an arbitrary class. That's
how Cheetah makes templates usable as Webware servlets, by subclassing
``Servlet``.  This technique should be possible for non-Webware systems
too.

(*Note:*\ ``FrogBase.tmpl`` could be improved by using the
``\#block`` directive, section \ref{inheritanceEtc.block}.)