File: tempuser.tex

package info (click to toggle)
albatross 1.35-2
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 2,328 kB
  • ctags: 1,702
  • sloc: python: 6,964; makefile: 139; sh: 123
file content (1211 lines) | stat: -rw-r--r-- 46,142 bytes parent folder | download | duplicates (5)
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
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Copyright 2001 by Object Craft P/L, Melbourne, Australia.
% LICENCE - see LICENCE file distributed with this software for details.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\chapter{Templates User Guide\label{tug-guide}}

There are many different ways which you can use Albatross to assist in
the construction of a web application.  The purpose of this guide is to
slowly introduce the features of Albatross to allow you to learn which
features can be useful in your application.

All of the example programs in this chapter are distributed with the
source in the \texttt{samples/templates} directory.

\section{Introduction to CGI\label{tug-simple1}}

This section presents a very simple program which will introduce you
to CGI programming.  This serves two purposes; it will verify that
your web server is configured to run CGI programs, and it will
demonstrate how simple CGI programming can be.

The sample program from this section is supplied in the
\texttt{samples/templates/simple1} directory and can be installed in
your web server \texttt{cgi-bin} directory by running the following
commands.

\begin{verbatim}
cd samples/templates/simple1
python install.py
\end{verbatim}

The \texttt{simple.py} program is show below.

\verbatiminput{../samples/templates/simple1/simple.py}

You can see the program output by pointing your browser
at \mbox{\url{\cgibindir/alsamp/simple1/simple.py}}.

If after installing the program locally you do not see a page
displaying the text ``Hello from my simple CGI application!'' then
you should look in the web server error log for clues.  The location
of the error log is specified by the \texttt{ErrorLog} directive in
the Apache configuration.  On a Debian Linux system the default
location is \texttt{/var/log/apache/error.log}.  While developing web
applications you will become intimately familiar with this file.

Knowing how Apache treats a request for a document in the
\texttt{cgi-bin} directory is the key to understanding how CGI programs
work.  Instead of sending the document text back to the browser Apache
executes the ``document'' and sends the ``document'' output back to
the browser.  This simple mechanism allows you to write programs which
generate HTML dynamically.

If you view the page source from the \texttt{simple1.py} application
in your browser you will note that the first two lines of output
produced by the program are not present.  This is because they are not
part of the document.  The first line is an HTTP (Hypertext Transfer
Protocol) header which tells the browser that the document content is
HTML.  The second line is blank which signals the end of HTTP headers
and the beginning of the document.

You can build quite complex programs by taking the simple approach of
embedding HTML within your application code.  The problem with doing
this is that program development and maintenance becomes a nightmare.
The essential implementation (or business level) logic is lost within
a sea of presentation logic.  The impact of embedding HTML in your
application can be reduced somewhat by using a package called
\texttt{HTMLgen}. \footnote{\texttt{HTMLgen} can be retrieved from
\url{http://starship.python.net/crew/friedrich/HTMLgen/html/main.html}.
On Debian Linux you can install the \texttt{htmlgen} package.}

The other way to make complex web applications manageable is to
separate the presentation layer from the application implementation
via a templating system.  This is also the Albatross way.

\section{Your First Albatross Program\label{tug-simple2}}

This section rewrites the sample CGI program from the previous section
as an Albatross program.  The program uses the Albatross templating
system to generate the HTML document.

The sample program from this section is supplied in the
\texttt{samples/templates/simple2} directory and can be installed in
your web server \texttt{cgi-bin} directory by running the following
commands.

\begin{verbatim}
cd samples/templates/simple2
python install.py
\end{verbatim}

All of the HTML is moved into a template file called
\texttt{simple.html}.

\verbatiminput{../samples/templates/simple2/simple.html}

The \texttt{simple.py} program is then rewritten as shown below.

\verbatiminput{../samples/templates/simple2/simple.py}

You can see the program output by pointing your browser
at \mbox{\url{\cgibindir/alsamp/simple2/simple.py}}.

This is probably the most simple application that you can write using
Albatross.  Let's analyse the program step-by-step.

This first line imports the Albatross package and places the
\class{SimpleContext} into the global namespace.

\begin{verbatim}
from albatross import SimpleContext
\end{verbatim}

Before we can use Albatross templates we must create an execution
context which will be used to load and execute the template file.  The
Albatross \class{SimpleContext} object should be used in programs
which directly load and execute template files.  The
\class{SimpleContext} constructor has a single argument which
specifies a path to the directory from which template files will be
loaded.  Before Apache executes a CGI program it sets the current
directory to the directory where that program is located.  We have
installed the template file in the same directory as the program,
hence the path \texttt{'.'}.

\begin{verbatim}
ctx = SimpleContext('.')
\end{verbatim}

Once we have an execution context we can load template files.  The
return value of the execution context \method{load_template()} method
is a parsed template.

\begin{verbatim}
templ = ctx.load_template('simple.html')
\end{verbatim}

Albatross templates are executed in two stages; the first stage
parses the template and compiles the embedded Python expressions, the
second actually executes the template.

To execute a template we call it's \method{to_html()} method passing
an execution context.  Albatross tags access application data and
logic via the execution context.  Since the template for the example
application does not refer to any application functionality, we do not
need to place anything into the context before executing the template.

\begin{verbatim}
templ.to_html(ctx)
\end{verbatim}

Template file output is accumulated in the execution context.

Unless you use one of the Albatross application objects you need to
output your own HTTP headers.

\begin{verbatim}
print 'Content-Type: text/html'
print
\end{verbatim}

Finally, you must explicitly flush the context to force the HTML to be
written to output.  Buffering the output inside the context allows
applications to trap and handle any exception which occurs while
executing the template without any partial output leaking to the
browser.

\begin{verbatim}
ctx.flush_content()
\end{verbatim}

\section{Introducing Albatross Tags\label{tug-simple3}}

In the previous section we presented a simple Albatross program which
loaded and executed a template file to generate HTML dynamically.  In
this section we will place some application data into the Albatross
execution context so that the template file can display it.

To demonstrate how Albatross programs separate application and
presentation logic we will look at a program which displays the CGI
program environment.  The sample program from this section is supplied
in the \texttt{samples/templates/simple3} directory and can be
installed in your web server \texttt{cgi-bin} directory by running the
following commands.

\begin{verbatim}
cd samples/templates/simple3
python install.py
\end{verbatim}

The CGI program \texttt{simple.py} is shown below.

\verbatiminput{../samples/templates/simple3/simple.py}

The following lines construct a sorted list of all defined environment
variables.  It makes the display a little nicer if the values are
sorted.

\begin{verbatim}
keys = os.environ.keys()
keys.sort()
\end{verbatim}

The Albatross execution context is constructed with an empty object in
the \member{locals} member which is used as a conduit between the
application and the toolkit.  It is used as the local namespace for
expressions evaluated in template files.  To make the environment
available to the template file we simply assign to an attribute using
a name of our choosing which can then be referenced by the template
file.

\begin{verbatim}
ctx.locals.keys = keys
ctx.locals.environ = os.environ
\end{verbatim}

The \class{SimpleContext} constructor save a reference ( in the
\member{globals} member) to the global namespace of the execution
context to the globals of the code which called the constructor.

Now the template file \texttt{simple.html}.  Two Albatross tags are
used to display the application data; \texttt{<al-for>} and
\texttt{<al-value>}.

\verbatiminput{../samples/templates/simple3/simple.html}

You can see the program output by pointing your browser
at \mbox{\url{\cgibindir/alsamp/simple3/simple.py}}.

The \texttt{<al-for>} Albatross tag iterates over the list of
environment variable names we placed in the \code{keys} value
(\code{ctx.locals.keys}).

All template file content enclosed by the \texttt{<al-for>} tag is
evaluated for each value in the sequence returned by evaluating the
\texttt{expr} attribute.  The \texttt{iter} attribute specifies the
name of the iterator which is used to retrieve each successive value
from the sequence.  The toolkit places the iterator object in the
\member{locals} member of the execution context.  Be careful that you
do not overwrite application values by using an iterator of the same
name as an application value.

The \texttt{<al-value>} Albatross tag is used to retrieve values from
the execution context.  The \texttt{expr} attribute can contain any
Python expression which can legally be passed to the Python
\code{eval()} function when the \var{kind} argument is
\texttt{"eval"}.

Deciding where to divide your application between implementation and
presentation can be difficult at times.  In the example above, we
implemented some presentation logic in the program; we sorted the list
of environment variables.  Let's make a modification which removes
that presentation logic from the application.

The \texttt{simple.py} application is shown below.

\verbatiminput{../samples/templates/simple4/simple.py}

Now look at the new \texttt{simple.html} template file.  By using the
Albatross \texttt{<al-exec>} tag we can prepare a sorted list of
environment variable names for the \texttt{<al-for>} tag.

\verbatiminput{../samples/templates/simple4/simple.html}

You can see the program output by pointing your browser
at \mbox{\url{\cgibindir/alsamp/simple4/simple.py}}.

The \texttt{<al-exec>} tag compiles the contents of the \texttt{expr}
tag by passing \texttt{"exec"} as the \var{kind} argument. This means
that you can include quite complex Python code in the attribute.
Remember that we want to minimise the complexity of the entire
application, not just the Python mainline.  If you start placing
application logic in the presentation layer, you will be back to
having an unmaintainable mess.

Just for your information, the \texttt{<al-exec>} tag could have been
written like this:

\begin{verbatim}
   <al-exec expr="
keys = environ.keys()
keys.sort()
">
\end{verbatim}

\subsection{Eliminating the Application\label{tug-naughty}}

Let's revisit our first Albatross application with the
\texttt{simple.py} sample program in the
\texttt{samples/templates/simple5} directory.

\verbatiminput{../samples/templates/simple5/simple.py}

Now consider the template file \texttt{simple.html}.

\verbatiminput{../samples/templates/simple5/simple.html}

You can see the program output by pointing your browser
at \mbox{\url{\cgibindir/alsamp/simple5/simple.py}}.

You will notice that we have completely removed any application logic
from the Python program.  This is a cute trick for small example
programs, but it is definitely a bad idea for any real application.

\section{Building a Useful Application\label{tug-content1}}

In the previous section we saw how Albatross tags can be used to
remove presentation logic from your application.  In this section we
will see how with a simple program we can serve up a tree of template
files.

If you look at the output of the \texttt{simple4/simple.py} program
you will notice the following lines:

\begin{verbatim}
REQUEST_URI     /cgi-bin/alsamp/simple4/simple.py
SCRIPT_FILENAME /usr/lib/cgi-bin/alsamp/simple4/simple.py
SCRIPT_NAME     /cgi-bin/alsamp/simple4/simple.py
\end{verbatim}

Now watch what happens when you start appending extra path elements to
the end of the URL.  Try requesting the following with your browser:
\mbox{\url{\cgibindir/alsamp/simple4/simple.py/main.html}}.

You should see the following three lines:

\begin{verbatim}
REQUEST_URI     /cgi-bin/alsamp/simple4/simple.py/main.html
SCRIPT_FILENAME /usr/lib/cgi-bin/alsamp/simple4/simple.py
SCRIPT_NAME     /cgi-bin/alsamp/simple4/simple.py
\end{verbatim}

The interesting thing is that Apache is still using the
\texttt{simple4/simple.py} program to process the browser request.  We
can use the value of the \texttt{REQUEST_URI} environment variable to
locate a template file which will be displayed.

The sample application in the \texttt{samples/templates/content1}
directory demonstrates serving dynamic content based upon the
requested URI.  The program can be installed in your web server
\texttt{cgi-bin} directory by running the following commands.

\begin{verbatim}
cd samples/templates/content1
python install.py
\end{verbatim}

The CGI program \texttt{content.py} is shown below.

\verbatiminput{../samples/templates/content1/content.py}

To demonstrate this application we have three template files;
\texttt{main.html}, \texttt{oops.html}, and \texttt{other.html}.

First \texttt{main.html}.

\verbatiminput{../samples/templates/content1/main.html}

Now \texttt{other.html}.

\verbatiminput{../samples/templates/content1/other.html}

And finally the page for displaying errors; \texttt{oops.html}.

\verbatiminput{../samples/templates/content1/oops.html}

Test the program by trying a few requests with your browser:

\indent
\mbox{\url{\cgibindir/alsamp/content1/content.py}} \\
\mbox{\url{\cgibindir/alsamp/content1/content.py/main.html}} \\
\mbox{\url{\cgibindir/alsamp/content1/content.py/other.html}} \\
\mbox{\url{\cgibindir/alsamp/content1/content.py/error.html}} \\
\mbox{\url{\cgibindir/alsamp/content1/content.py/oops.html}}

Let's analyse the program step-by-step.  The preamble imports the
modules we are going to use.

\begin{verbatim}
#!/usr/bin/python
import os
from albatross import SimpleContext, TemplateLoadError
\end{verbatim}

The next part of the program removes the prefix in the
\texttt{SCRIPT_NAME} variable from the value in the
\texttt{REQUEST_URI} variable.  When removing the script name we add
one to the length to ensure that the \texttt{"/"} path separator
between the script and page is also removed.  This is important
because the execution context \method{load_template()} method uses
\code{os.path.join()} to construct a script filename by combining the
\var{base_dir} specified in the constructor and the name passed to the
\method{load_template()} method.  If any of the path components being
joined begin with a \texttt{"/"} then \code{os.path.join()} creates an
absolute path beginning at the \texttt{"/"}.

If no page was specified in the browser request then we use the
default page \texttt{main.html}.

\begin{verbatim}
script_name = os.environ['SCRIPT_NAME']
request_uri = os.environ['REQUEST_URI']
page = request_uri[len(script_name) + 1:]
if not page:
    page = 'main.html'
\end{verbatim}

The next section of code creates the Albatross execution context and
places the requested filename into the \code{page} local attribute.
It then attempts to load the requested file.  If the template file
does not exist the \method{load_template()} will raise a
\code{TemplateLoadError} exception.  We handle this by loading the
error page \texttt{oops.html}.

The error page displays a message which explains that the requested
page (saved in the \code{page} variable) does not exist.

\begin{verbatim}
ctx = SimpleContext('templ')
ctx.locals.page = page
try:
    templ = ctx.load_template(page)
except TemplateLoadError:
    templ = ctx.load_template('oops.html')
\end{verbatim}

Looking at the error page \texttt{oops.html}, you will see a new
Albatross tag \texttt{<al-if>}.

\begin{verbatim}
  <al-if expr="page == 'oops.html'">
   You actually requested the error page!
  <al-else>
   Sorry, the page <font color="red"><al-value expr="page"></font>
   does not exist.
  </al-if>
\end{verbatim}

The \texttt{<al-if>} tag allows you to conditionally include or
exclude template content by testing the result of an expression.
Remember that we placed the name of the requested page into the
\code{page} variable, so we are able to display different content when
the browser actually requests \texttt{oops.html}.

Finally, the remainder of the program displays the selected HTML page.

\begin{verbatim}
templ.to_html(ctx)

print 'Content-Type: text/html'
print
ctx.flush_content()
\end{verbatim}

\section{Albatross Macros\label{tug-content2}}

In the previous section we demonstrated a program which can be used to
display pages from a collection of template files.  You might recall
that the HTML in the template files was very repetitive.  In this
section you will see how Albatross macros can be used to introduce a
common look to all HTML pages.

If we look at the \texttt{main.html} template file again you will
notice that there really is very little content which is unique to
this page.

\verbatiminput{../samples/templates/content1/main.html}

Using Albatross macros we can place all of the boilerplate into a
macro.  Once defined, the macro can be reused in all template files.

The sample program from this section is supplied in the
\texttt{samples/templates/content2} directory and can be installed in
your web server \texttt{cgi-bin} directory by running the following
commands.

\begin{verbatim}
cd samples/templates/content2
python install.py
\end{verbatim}

First consider the macro in the \texttt{macros.html} template file.

\verbatiminput{../samples/templates/content2/macros.html}

Now we can change \texttt{main.html} to use the macro.

\verbatiminput{../samples/templates/content2/main.html}

Likewise, the \texttt{other.html} file.

\verbatiminput{../samples/templates/content2/other.html}

And finally the error page \texttt{oops1.html}.

\verbatiminput{../samples/templates/content2/oops.html}

We also have to modify the application to load the macro definition
before loading the requested pages.

\verbatiminput{../samples/templates/content2/content.py}

Test the program by trying a few requests with your browser:

\indent
\mbox{\url{\cgibindir/alsamp/content2/content.py}} \\
\mbox{\url{\cgibindir/alsamp/content2/content.py/main.html}} \\
\mbox{\url{\cgibindir/alsamp/content2/content.py/other.html}} \\
\mbox{\url{\cgibindir/alsamp/content2/content.py/error.html}} \\
\mbox{\url{\cgibindir/alsamp/content2/content.py/oops.html}}

The only new line in this program is the following:

\begin{verbatim}
ctx.load_template('macros.html').to_html(ctx)
\end{verbatim}

This loads the file which contains the macro definition and then
executes it.  Executing the macro definition registers the macro with
the execution context, it does not produce any output.  This means
that once defined the macro is available to all templates interpreted
by the execution context.  The template is not needed once the macro
has been registered so we can discard the template file.

When you use Albatross application objects the macro definition is
registered in the application object so can be defined once and then
used with all execution contexts.

There is one small problem with the program.  What happens if the
browser requests \texttt{macros.html}?  Suffice to say, you do not get
much useful output.  The way to handle this problem is to modify the
program to treat requests for \texttt{macros.html} as an error.

Let's revisit the macro definition in \texttt{macros.html} and see how
it works.  Albatross macros use four tags; \texttt{<al-macro>},
\texttt{<al-usearg>}, \texttt{<al-expand>}, and \texttt{<al-setarg>}.

\verbatiminput{../samples/templates/content2/macros.html}

The \texttt{<al-macro>} tag is used to define a named macro.  The
\texttt{name} attribute uniquely identifies the macro within the
execution context.  In our template file we have defined a macro
called \texttt{"doc"}.  All content enclosed in the
\texttt{<al-macro>} tag will be substituted when the macro is expanded
via the \texttt{<al-expand>} tag.

In all but the most simple macros you will want to pass some arguments
to the macro.  The place where the arguments will be expanded is
controlled via the \texttt{<al-usearg>} tag in the macro definition.
All macros accept an ``unnamed'' argument which captures all of the
content within the \texttt{<al-expand>} tag not enclosed by
\texttt{<al-setarg>} tags.  The unnamed argument is retrieved within
the macro definition by using \texttt{<al-usearg>} without specifying
a \texttt{name} attribute.

In our example we used a fairly complex macro.  If you are still a bit
confused the following sections should hopefully clear up that
confusion.

\subsection{Zero Argument Macros\label{tug-zeromacro}}

The most simple macro is a macro which does not accept any arguments.
You might define the location of the company logo within a zero
argument macro.

\begin{verbatim}
<al-macro name="small-logo">
<img src="http://images.company.com/logo/small.png">
</al-macro>
\end{verbatim}

Then whenever you need to display the logo all you need to do is
expand the macro.

\begin{verbatim}
<al-expand name="small-logo"/>
\end{verbatim}

This allows you to define the location and name of your company logo
in one place.

\subsection{Single Argument Macros\label{tug-singlemacro}}

The single argument macro is almost as simple as the zero argument
macro.  You should always use the unnamed argument to pass content to
a single argument macro.

If you look at news sites such as \url{http://slashdot.org/} you will
note that they make heavy use of HTML tricks to improve the
presentation of their pages.  Single argument macros can be extremely
useful in simplifying your template files by moving the complicated
HTML tricks into a separate macro definition file.

Let's look at the top story at \url{http://slashdot.org/} to
illustrate the point.  The title bar for the story is constructed with
the following HTML (reformatted so it will fit on the page).

\begin{verbatim}
<table width="100%" cellpadding=0 cellspacing=0 border=0>
<tr>
<td valign=top bgcolor="#006666">
<img src="http://images.slashdot.org/slc.gif" width=13 height=16 alt="" align=top>
<font size=4 color="#FFFFFF" face="arial,helvetica">
<b>Another Nasty Outlook Virus Strikes</b>
</font>
</td>
</tr>
</table>
\end{verbatim}

As you can see, most of the HTML is dedicated to achieving a certain
effect.  If you were using Albatross to construct the same HTML you
would probably create a macro called \texttt{story-title} like this:

\begin{verbatim}
<al-macro name="story-title">
<table width="100%" cellpadding=0 cellspacing=0 border=0>
<tr>
<td valign=top bgcolor="#006666">
<img src="http://images.slashdot.org/slc.gif" width=13 height=16 alt="" align=top>
<font size=4 color="#FFFFFF" face="arial,helvetica">
<b><al-usearg></b>
</font>
</td>
</tr>
</table>
</al-macro>
\end{verbatim}

Then you could generate the story title HTML like this:

\begin{verbatim}
<al-expand name="story-title">Another Nasty Outlook Virus Strikes</al-expand>
\end{verbatim}

Since stories are likely to be generated from some sort of database it
is more likely that you would use something like this:

\begin{verbatim}
<al-expand name="story-title"><al-value expr="story.title"></al-expand>
\end{verbatim}

\subsection{Multiple Argument Macros\label{tug-multimacro}}

Multiple argument macros are effectively the same as single argument
macros that accept additional named arguments.

The following example shows a macro that defines multiple arguments
and some template to expand the macro.

\begin{verbatim}
<al-macro name="multi-arg">
arg1 is "<al-usearg name="arg1">" and
arg2 is "<al-usearg name="arg2">" and
the default argument is "<al-usearg>".
</al-macro>

<al-expand name="multi-arg">
This is <al-setarg name="arg2">arg2 content</al-setarg>
the <al-setarg name="arg1">arg1 content</al-setarg>
default argument</al-expand>
\end{verbatim}

When the above template is executed the following output is produced.

\begin{verbatim}
arg1 is "arg1 content" and
arg2 is "arg2 content" and
the default argument is "This is the default argument".
\end{verbatim}

\subsection{Nesting Macros\label{tug-nestmacro}}

Let's revisit the \url{http://slashdot.org/} HTML for a story and see
how to use macros to assist in formatting the entire story summary.

Consider the rest of the story summary minus the header (reformatted
to fit on the page):

\begin{verbatim}
<a HREF="http://slashdot.org/search.pl?topic=microsoft">
<img SRC="http://images.slashdot.org/topics/topicms.gif" WIDTH="75" HEIGHT="55"
	BORDER="0" ALIGN="RIGHT" HSPACE="20" VSPACE="10" ALT="Microsoft">
</a>
<b>Posted by <a HREF="http://www.monkey.org/~timothy">timothy</a>
 on  Sunday July 22, @11:32PM</b><br>
<font size=2><b>from the hide-the-children-get-the-gun dept.</b></font><br>
Goldberg's Pants writes: <i>
"<a HREF="http://www.zdnet.com/zdnn/stories/news/0,4586,2792260,00.html?chkpt=zdnnp1tp02">ZDNet</a>
and <a HREF="http://www.wired.com/news/technology/0,1282,45427,00.html">Wired</a>
are both reporting on a new virus that spreads via Outlook. Nothing
particularly original there, except this virus is pretty unique both
in how it operates, and what it does, such as emailing random
documents from your harddrive to people in your address book, and
hiding itself in the recycle bin which is rarely checked by virus
scanners."</i> I talked by phone with a user whose machine seemed
determined to send me many megabytes of this virus 206k at a time; he
was surprised to find that his machine was infected, as most people
probably would be. The anti-virus makers have patches, if you are
running an operating system which needs them.
\end{verbatim}

The first task is to simplify is the topic specific image.  There are
a finite number of topics, and the set of topics does not change much
over time.  We could make effective use of the Albatross
\texttt{<al-lookup>} tag to simplify this (\texttt{<al-lookup>} is
discussed in section \ref{tug-lookup}):

\begin{verbatim}
<al-lookup name="story-topic">
 <al-item expr="'microsoft'">
  <a HREF="http://slashdot.org/search.pl?topic=microsoft">
   <img SRC="http://images.slashdot.org/topics/topicms.gif" WIDTH="75"
        HEIGHT="55" BORDER="0" ALIGN="RIGHT" HSPACE="20" VSPACE="10"
        ALT="Microsoft">
  </a>
 </al-item>
 <al-item expr="'news'">
   :
 </al-item>
</al-lookup>
\end{verbatim}

Then to display the HTML for the story topic all we would need to do
is the following:

\begin{verbatim}
<al-value expr="story.topic" lookup="story-topic">
\end{verbatim}

Next we will simplify the acknowledgement segment:

\begin{verbatim}
<b>Posted by <al-value expr="story.poster" noescape>
 on <al-value expr="story.date" date="%A %B %d, @%I:%M%p"></b><br>
<font size=2><b>from the <al-value expr="story.dept"> dept.</b></font><br>
\end{verbatim}

Finally we can bring all of these fragments together like this:

\begin{verbatim}
<al-macro name="story-summary">
 <al-expand name="story-title"><al-value name="story.title"></al-expand>
 <al-value expr="story.topic" lookup="story-topic">
 <b>Posted by <al-value expr="story.poster">
 on <al-value expr="story.date" date="%A %B %d, @%I:%M%p"></b><br>
 <font size=2><b>from the <al-value expr="story.dept"> dept.</b></font><br>
 <al-value expr="story.summary" noescape>
</al-macro>
\end{verbatim}

Having defined the macro for formatting a story summary we can format
a list of story summaries like this:

\begin{verbatim}
<al-for iter="i" expr="summary_list">
 <al-exec expr="story = i.value()">
 <al-expand name="story-summary"/>
</al-for>
\end{verbatim}

Notice that all of the macros are referring directly to the
\code{story} object which contains all of the data which pertains to
one story.

If you find that your macros are referring to application data by name
then you should consider using a function instead.  Once functions
have been implemented you might be able to use them as well as
consider them.

\section{Lookup Tables\label{tug-lookup}}

The example macro used in the previous section introduced a new
Albatross tag called \texttt{<al-lookup>}.  In this section we will
look at the tag in more detail.

The \texttt{<al-lookup>} tag provides a mechanism for translating
internal program values into HTML for display.  This is another way
which Albatross allows you to avoid placing presentation logic in your
application.

In a hypothetical bug tracking system we have developed we need to
display information about bugs recorded in the system.  The severity
of a bug is defined by a collection of symbols defined in the
\module{btsvalues} module.

\begin{verbatim}
TRIVIAL = 0
MINOR = 1
NORMAL = 2
MAJOR = 3
CRITICAL = 4
\end{verbatim}

While the integer severity levels are OK for use as internal program
values they are not very useful as displayed values.  The obvious way
to display a bug severity would be via the \texttt{<al-value>} tag.

\begin{verbatim}
Severity: <al-value expr="bug.severity">
\end{verbatim}

Unfortunately, this would yield results like this:

\begin{verbatim}
Severity: 1
\end{verbatim}

By using the \texttt{lookup} attribute of the \texttt{<al-value>} tag
we are able to use the internal value as an index into a lookup table.
The corresponding entry from the lookup table is displayed instead of
the index.

The following is a table which translates the internal program value
into HTML for display.

\begin{verbatim}
<al-lookup name="bug-severity">
 <al-item expr="btsvalues.TRIVIAL"><font color="green">Trivial</font></al-item>
 <al-item expr="btsvalues.MINOR">Minor</al-item>
 <al-item expr="btsvalues.NORMAL">Normal</al-item>
 <al-item expr="btsvalues.MAJOR"><font color="red">Major</font></al-item>
 <al-item expr="btsvalues.CRITICAL"><font color="red"><b>Critical</b></font></al-item>
</al-lookup>
\end{verbatim}

The \module{btsvalues} module must be visible when the
\texttt{<al-lookup>} tag is executed.  You can place the
\module{btsvalues} module in the the global namespace of the execution
context by importing the \module{btsvalues} module in the same module
which creates the \class{SimpleContext} execution context.  When using
other Albatross execution contexts you would need to import
\module{btsvalues} in the module which called \method{run_template()}
or \method{run_template_once()} to execute the \texttt{<al-lookup>}
tag.

We invoke the lookup table by using the \texttt{lookup} attribute of
the \texttt{<al-value>} tag.

\begin{verbatim}
Severity: <al-value expr="bug.severity" lookup="bug-severity">
\end{verbatim}

Note that the \module{btsvalues} module does not need to be in the
namespace at this point.  The \texttt{expr} attributes in the
\texttt{<a-item>} tags are evaluated once when the
\texttt{<al-lookup>} tag is executed.

The \texttt{<al-lookup>} tag has the same runtime properties as the
\texttt{<al-macro>} tag.  You have execute the tag to register the
lookup table with the execution context.  Once the lookup table has
been registered it is available to all template files executed in the
same execution context.

When using Albatross application objects the lookup table is
registered in the application object so can be defined once and then
used with all execution contexts.

Each entry in the lookup table is enclosed in a \texttt{<al-item>}
tag.  The \texttt{expr} attribute of the \texttt{<al-item>} tag
defines the expression which will be evaluated to determine the item's
table index.  As explained above, the expression is evaluated when the
lookup table is executed, not when the table is loaded, or looked up
(with the rare exception of a lookup being used earlier in the same
template file that it is defined).

It is important to note that the content enclosed by the
\texttt{<al-item>} tag is executed when the item is retrieved via an
\texttt{<al-value>} tag.  This allows you to place Albatross tags
inside the lookup table that are designed to be evaluated when the
table is accessed.

Finally, any content not enclosed by an \texttt{<al-item>} tag will be
returned as the result of a failed table lookup.

\section{White Space Removal in Albatross\label{tug-white}}

If you were paying close attention to the results of expanding the
macros we created in section \ref{tug-content2} you would have noticed
that nearly all evidence of the Albatross tags has disappeared.  It is
quite obvious that the Albatross tags are no longer present.  A little
less obvious is removal of whitespace following the Albatross tags.

Let's have a look at the \texttt{"doc"} macro again.

\verbatiminput{../samples/templates/content2/macros.html}

We can get a capture the result of expanding the macro by firing up
the Python interpreter to manually exercise the macro.

\verbatiminput{doctest/templ-white1}

Not only have the \texttt{<al-macro>} and \texttt{<al-expand>} tags
been removed, the whitespace that follows those tags has also been
removed.  By default Albatross removes all whitespace following an
Albatross tag that begins with a newline.  This behaviour should be
familiar to anyone who has used PHP.

Looking further into the result you will note that the
\texttt{</body>} tag is aligned with the \texttt{<hr~noshade>} tag
above it.  This is the result of performing the \texttt{<al-usearg>}
substitution (which had no content) and removing all whitespace
following the \texttt{<al-usearg>} tag.

This whitespace removal nearly always produces the desired result,
though it can be a real problem at times.

\verbatiminput{doctest/templ-white2}

The whitespace removal has definitely produced an undesirable result.

You can always get around the problem by joining all of the
\texttt{<al-value>} tags together on a single line.  Remember that the
whitespace removal only kicks in if the whitespace begins with a
newline character.  For our example this would be a reasonable
solution.

\verbatiminput{doctest/templ-white3}

The other way to defeat the whitespace removal while keeping each
\texttt{<al-value>} tag on a separate line would be to place a single
trailing space at the end of each line.  This would be a very bad idea
because the next person to modify the file might remove the space
without realising how important it was.

Note that there are trailing spaces at the end of each line in the
\code{text} assignment.  This should give you a clue about how bad
this technique is.

\verbatiminput{doctest/templ-white4}

A much better way to solve the problem is to explicitly tell the
Albatross parser that you want it to do something different with the
whitespace that follows the first two \texttt{<al-value>} tags.

\verbatiminput{doctest/templ-white5}

The above variation has told the Albatross interpreter to only strip
the trailing newline, leaving intact the indent on the following line.
The following table describes all of possible values for the
\texttt{whitespace} attribute.

\begin{longtableii}{l|l}{textrm}{Value}{Meaning}
\lineii{\code{'all'}}{Keep all following whitespace.}
\lineii{\code{'strip'}}{Remove all whitespace -  this is the default.}
\lineii{\code{'indent'}}{Keep indent on following line.}
\lineii{\code{'newline'}}{Remove all whitespace and substitute a newline.}
\end{longtableii}

Note that when the trailing whitespace does not begin with a newline
the \code{'strip'} and \code{'indent'} whitespace directives are treated
exactly like \code{'all'}.

\section{Using Forms to Receive User Input\label{tug-form1}}

Nearly all web applications need to accept user input.  User input is
captured by using forms.  We will begin by demonstrating the
traditional approach to handling forms, then in later sections you
will see how Albatross can be used to eliminate the tedious shuffling
of application values in and out of form elements.

Let's start with a program that presents a form to the user and
displays to user response to the form.  The sample program from this
section is supplied in the \texttt{samples/templates/form1} directory
and can be installed in your web server \texttt{cgi-bin} directory by
running the following commands.

\begin{verbatim}
cd samples/templates/form1
python install.py
\end{verbatim}

The CGI program \texttt{form.py} is shown below.

\verbatiminput{../samples/templates/form1/form.py}

There are no surprises here, we are using the standard Python
\module{cgi} module to capture the browser request.  We want to
display the contents of the request so it is placed into the execution
context.

The \texttt{form.html} template file is used to display present a form
and display the browser request.

\verbatiminput{../samples/templates/form1/form.html}

We have placed the form display logic in a separate template file
because we wish to reuse that particularly nasty piece of template.
The form display template is contained in \texttt{form-display.html}.

If you do not understand how the \class{FieldStorage} class from the
\module{cgi} module works, do not try to understand the following
template.  Refer to section \ref{tug-form2} which contains a small
explanation of the \class{FieldStorage} class and some Python code
that performs the same task as the template.

\verbatiminput{../samples/templates/form1/form-display.html}

You can see the program output by pointing your browser
at \mbox{\url{\cgibindir/alsamp/form1/form.py}}.

You will notice that each time you submit the page it comes back with
all of the fields cleared again.

Typically web applications that generate HTML dynamically will hand
construct \texttt{<input>} tags and place application values into the
\texttt{value} attributes of the input tags.  Since we are using
Albatross templates we do not have the ability to construct tags on
the fly without doing some very nasty tricks.  Fortunately Albatross
supplies some tags that we can use in place of the standard HTML
\texttt{<input>} tags.

\section{Using Albatross Input Tags\label{tug-form2}}

In the previous section we saw how web applications can capture user
input from browser requests.  This section explains how Albatross
\texttt{<al-input>} tags can be used to take values from the execution
context and format them as \texttt{value} attributes in the HTML
\texttt{<input>} tags sent to the browser.

The sample program from this section is supplied in the
\texttt{samples/templates/form2} directory and can be installed in
your web server \texttt{cgi-bin} directory by running the following
commands.

\begin{verbatim}
cd samples/templates/form2
python install.py
\end{verbatim}

The first change is in the \texttt{form.html} template file.

\verbatiminput{../samples/templates/form2/form.html}

We need to place some values into the execution context so that the
Albatross \texttt{<al-input>} tags can display them.  The easiest
thing to do is to place the browser submitted values into the
execution context.

The documentation for the Python \module{cgi} module is quite good so
I will not try to explain the complete behaviour of the
\class{FieldStorage} class.  The only behaviour that we need to be
aware of for our program is what it does when it receives more than
one value for the same field name.

The \class{FieldStorage} object that captures browser requests behaves
like a dictionary that is indexed by field name.  When the browser
sends a single value for a field, the dictionary lookup yields an
object containing the field value in the \member{value} member.  When
the browser sends more than one value for a field, the dictionary
lookup returns a list of the objects used to represent a single field
value.

Using this knowledge, the \texttt{form.py} program can be modified to
merge the browser request into the execution context.

\verbatiminput{../samples/templates/form2/form.py}

You can see the program output by pointing your browser
at \mbox{\url{\cgibindir/alsamp/form2/form.py}}.

You will notice that your input is sent back to you as the default
value of each form element.

When you use Albatross application objects the browser request is
automatically merged into the execution context for you.

\section{More on the \texttt{<al-select>} Tag\label{tug-form3}}

In the previous section we performed a direct translation of the
standard HTML input tags to the equivalent Albatross tags.  In
addition to a direct translation from the HTML form, the
\texttt{<al-select>} tag supports a dynamic form.

In all but the most simple web application you will occasionally need
to define the options in a \texttt{<select>} tag from internal
application values.  In some ways the dynamic form of the
\texttt{<al-select>} tag is easier to use than the static form.

The sample program from this section is supplied in the
\texttt{samples/templates/form3} directory and can be installed in
your web server \texttt{cgi-bin} directory by running the following
commands.

\begin{verbatim}
cd samples/templates/form3
python install.py
\end{verbatim}

The form from section \ref{tug-form2} has been modified to include two
\texttt{<al-select>} tags, and as shown below.

\verbatiminput{../samples/templates/form3/form.html}

The \texttt{<al-select>} tags demonstrate the two ways that you can
define option lists in your code using the \texttt{optionexpr}
attribute.  When converting the tag to HTML the expression in the
\texttt{optionexpr} attribute is evaluated and the result is used to
generate the option list that appears in the generated HTML.

The \texttt{<form.py>} program has been modified to supply lists of
option values.

\verbatiminput{../samples/templates/form3/form.py}

You can see the program output by pointing your browser
at \mbox{\url{\cgibindir/alsamp/form3/form.py}}.

If you view the browser source produced by the two
\texttt{<al-select>} tags you will see the difference between the way
that both option list forms are handled.  Note in particular that the
tuples in \code{option_list2} contain an integer value as the first
element.  This is converted to string when it is compared with the
value stored in \code{select2} to determine which option is selected.

The browser request sent to the application will always contain
strings for field values.

\section{Streaming Application Output to the Browser\label{tug-stream1}}

By default Albatross buffers all HTML generated from templates inside
the execution context and sends a complete page once the template
execution has completed (via the \method{flush_content()} method).  The
advantage of buffering the HTML is that applications can handle
exceptions that occur during execution of the template and prevent
any partial results leaking to the browser.

Sometimes your application needs to perform operations which take a
long time.  Buffering all output while lengthy processing occurs makes
the application look bad.  Albatross lets you use the
\texttt{<al-flush>} tag to mark locations in your template file where
any accumulated HTML should be flushed to the browser.  The only downside
to using this tag is that you lose the ability to completely insulate
the user from a failure in template execution.

The sample program from this section is supplied in the
\texttt{samples/templates/stream} directory and can be installed in
your web server \texttt{cgi-bin} directory by running the following
commands.

\begin{verbatim}
cd samples/templates/stream
python install.py
\end{verbatim}

The \texttt{stream.py} program is shown below.

\verbatiminput{../samples/templates/stream/stream.py}

We have simulated a slow process by building a class that acts like a
sequence of 10 elements that each take one second to retrieve.

We must make sure that we send the HTTP headers before calling the
template execution (\method{to_html()} method).  This is necessary
since the execution of the template is going to cause HTML to be sent
to the browser.

Now let's look at the \texttt{stream.html} template file that displays
the results of our slow process.

\verbatiminput{../samples/templates/stream/stream.html}

You can see the program output by pointing your browser
at \mbox{\url{\cgibindir/alsamp/stream/stream.py}}.

\section{Displaying Tree Structured Data\label{tug-tree}}

One of the more powerful tags in the Albatross toolkit is the
\texttt{<al-tree>} tag.  This tag can be used to display almost any
data that is tree structured.

The best way to explain the tag is by example.  Consider the
\texttt{samples/templates/tree/tree.py} sample program.  This is a
standalone program that is intended to be run from the command line.

\verbatiminput{../samples/templates/tree/tree.py}

The program constructs a tree of \class{Node} objects then passes the
root of the tree to the \texttt{tree.html} template for formatting.
The \texttt{samples/templates/tree/tree.html} template file looks like
this:

\verbatiminput{../samples/templates/tree/tree.html}

When you run the program it produces the following result.

\begin{verbatim}
-a
 |-b
 | |-c
 | \-d
 \-e
   |-f
   | \-g
   |   |-h
   |   \-i
   |-j
   \-k
     |-l
     \-m
\end{verbatim}

Internally the \texttt{<al-tree>} tag uses a special iterator that is
an instance of the \class{TreeIterator} class.  This iterator performs
a pre-order traversal of the tree returned by the \texttt{expr}
attribute of the tag.  The only requirement of the tree node objects
is that child nodes are stored in the \member{children} sequence
member.

The \texttt{<al-tree>} tag also supports a more powerful lazy loading
mode of operation which is supported by Albatross application objects.
Refer to section \ref{tag-tree}.