3.3 Introducing Albatross Tags

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 samples/templates/simple3 directory and can be installed in your web server cgi-bin directory by running the following commands.

cd samples/templates/simple3
python install.py

The CGI program simple.py is shown below.

#!/usr/bin/python
import os
from albatross import SimpleContext

ctx = SimpleContext('.')
templ = ctx.load_template('simple.html')

keys = os.environ.keys()
keys.sort()
ctx.locals.keys = keys
ctx.locals.environ = os.environ

templ.to_html(ctx)

print 'Content-Type: text/html'
print
ctx.flush_content()

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

keys = os.environ.keys()
keys.sort()

The Albatross execution context is constructed with an empty object in the 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.

ctx.locals.keys = keys
ctx.locals.environ = os.environ

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

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

<html>
 <head>
  <title>The CGI environment</title>
 </head>
 <body>
  <table>
   <al-for iter="name" expr="keys">
    <tr>
     <td><al-value expr="name.value()"></td>
     <td><al-value expr="environ[name.value()]"></td>
    <tr>
   </al-for>
  </table>
 </body>
</html>

You can see the program output by pointing your browser at http://www.object-craft.com.au/cgi-bin/alsamp/simple3/simple.py.

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

All template file content enclosed by the <al-for> tag is evaluated for each value in the sequence returned by evaluating the expr attribute. The 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 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 <al-value> Albatross tag is used to retrieve values from the execution context. The expr attribute can contain any Python expression which can legally be passed to the Python eval() function when the kind argument is "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 simple.py application is shown below.

#!/usr/bin/python
import os
from albatross import SimpleContext

ctx = SimpleContext('.')
templ = ctx.load_template('simple.html')

ctx.locals.environ = os.environ

templ.to_html(ctx)

print 'Content-Type: text/html'
print
ctx.flush_content()

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

<html>
 <head>
  <title>The CGI environment</title>
 </head>
 <body>
  <table>
   <al-exec expr="keys = environ.keys(); keys.sort()">
   <al-for iter="name" expr="keys">
    <tr>
     <td><al-value expr="name.value()"></td>
     <td><al-value expr="environ[name.value()]"></td>
    <tr>
   </al-for>
  </table>
 </body>
</html>

You can see the program output by pointing your browser at http://www.object-craft.com.au/cgi-bin/alsamp/simple4/simple.py.

The <al-exec> tag compiles the contents of the expr tag by passing "exec" as the 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 <al-exec> tag could have been written like this:

   <al-exec expr="
keys = environ.keys()
keys.sort()
">


Subsections