6. Developing Custom Tags

In most complex applications you are likely to encounter presentation problems which the standard collection of tags cannot easily solve. Albatross provides a set of classes in the albatross.template module which are designed to allow the development of custom tags.

The albatross module performs from template import * so all contents of albatross.template are available in albatross.

The following is a simple calendar tag which formats a single month like the unix cal(1) program.

import time
import calendar
import albatross

class Calendar(albatross.EmptyTag):
    name = 'alx-calendar'

    def to_html(self, ctx):
        year = self.get_attrib('year')
        if year is not None:
            year = ctx.eval_expr(year)
        month = self.get_attrib('month')
        if month is not None:
            month = ctx.eval_expr(month)
        if month is None or year is None:
            now = time.localtime(time.time())
            if year is None:
                year = now[0]
            if month is None:
                month = now[1]
        ctx.write_content('<table>\n')
        ctx.write_content('<tr align="center"><td colspan="7">%s %s</td></tr>\n' \
                          % (calendar.month_name[month], year))
        ctx.write_content('<tr>')
        for i in range(7):
            ctx.write_content('<td>%s</td>' \
                              % calendar.day_abbr[(i + 6) % 7][:2])
        ctx.write_content('</tr>\n')
        calendar.setfirstweekday(6)
        for r in calendar.monthcalendar(year, month):
            ctx.write_content('<tr align="right">')
            for i in range(7):
                if r[i]:
                    ctx.write_content('<td>%s</td>' % r[i])
                else:
                    ctx.write_content('<td></td>')
            ctx.write_content('</tr>\n')
        ctx.write_content('</table>\n')

To use the tag in your application you must make the class available to the execution context. If you are using an Albatross application object you can do this by passing the class to the register_tagclasses() method of the application object.

from albatross import SimpleApp

app = SimpleApp('ext.py', '.', 'start')
app.register_tagclasses(Calendar)

All Albatross application classes inherit from the ResourceMixin in the albatross.context module. Execution contexts which are used with application objects inherit from the AppContext class from the albatross.app module which automatically retrieves all resources from the parent application object.

If you are using the SimpleContext class for your execution context then you will need to call the register_tagclasses() method of the execution context immediately after construction.

The following is an example template file which uses the <alx-calendar> tag.

<html>
<head><title>Calendar for <al-value expr="year"></title></head>
<body>
<h1>Calendar for <al-value expr="year"></h1>
<table cellpadding="10">
<al-for iter="r" expr="range(1,13)" cols="3" flow="across">
 <tr valign="top">
 <al-for iter="m" expr="r.value()">
  <td><alx-calendar month="m.value()" year="year"></td>
 </al-for>
 </tr>
</al-for>
</table>
</body>
</html>

A complete program which uses this extension tag and template file can be found in the samples/extension directory. Use the install.py script to install the sample.

cd samples/extension
python install.py


Subsections