We have an informal in-house style that says alternating rows of table data
should have different background colors, so that it is easy to keep track of
which row is which. This is done by alternating the "class" attribute of each
"
" tag. In trying to use Albatross, I wound up doing lots of code like {{{
}}}
Not only is this ugly to look at and a lot to type, it really messes with the
head of the HTML editor (I use xemacs) and breaks the indentation.
So we wrote an extension tag to hide all this nastyness. I include
it here in case anyone else finds it interesting. (This version is for Albatross 1.10; you can find a version for Albatross 1.01 by looking at old versions of this page)
{{{
#!python
'''
A collection of useful custom tag classes for use with the albatross library.
To make these available, simply pass the class object to the
register_tagclasses() member of the application object.
E.g.:
import itgatags
....
class MyApp(SimpleApp):
def __init__(self):
SimpleApp.__init__(self,......)
for page_class in (.......):
self .register_page(page_class.name, page_class())
for tag_class in (itgatags.TR,):
self .register_tagclasses(tag_class)
'''
from albatross.tags import EvalAttribMixin
from albatross import EnclosingTag
class TR(EnclosingTag, EvalAttribMixin):
'''
...
Similar to , except that it evaluates expr (which must be an
integer) and then chooses a "class=" attribute for the
tag
from those listed in the "classes" arg by taking " % <# of
classes>". is often "i.index()" where i is an iterator
created by .
This is useful for having rows of the table with alternating or
successive styles. Elements of the "classes" list may be empty
(i.e. "alt1,") or the empty string ("alt1,'',alt2") which will
produce a without a "class=" attribute.
"classes" may be omitted and defaults to ",alt" (i.e. alternating
normal and "class=alt" styles. Naturally, you will need some sort
of stylesheet definitions for these classes.
Example:
This will produce a table where the odd rows are normal, but the
2nd and 4th rows have special class (and hence presumably special
formatting).
...
Similar to the above, but instead of evaluating an expression,
this uses a counter with the given name in the ctx.locals space
(creating it with the value 0 if necessary). The counter will be
incremented after it is used. This is useful if a single table
contains rows from multiple tags, or summary lines at the
bottom, or similar. It can also count the number of rows for you!
Example:
Rows Added.
Using a counter rather than the iterator.index() method ensures
that the TOTAL row has the appropriate and consistant class
attribute.
'''
name = 'alx-tr'
def __init__(self, ctx, filename, line_num, attribs):
EnclosingTag.__init__(self, ctx, filename, line_num, attribs)
if self.has_attrib('expr'):
self.counter = ''
elif self.has_attrib('counter'):
self.counter = self.get_attrib('counter')
else:
self.raise_error('missing "counter" or "expr" attribute')
if self.has_attrib('classes'):
cs = self.get_attrib('classes')
self.classes = []
for c in cs.split(','):
if c == "''" or c == '""':
c = ''
self.classes.append(c)
else:
self.classes = ['', 'alt']
def to_html(self, ctx):
if self.counter:
if ctx.has_value(self.counter):
val = ctx.get_value(self.counter)
else:
val = 0
else: # expr
val = int(self.eval_attrib(ctx, 'expr'))
cls = self.classes[val % len(self.classes)]
if cls:
ctx.write_content('' % cls)
else:
ctx.write_content('
')
self.content.to_html(ctx)
ctx.write_content('
\n')
if self.counter:
ctx.set_value(self.counter, val + 1)
}}}
----
Nice. Another approach, although not as simple to read as the custom tag, uses the standard .
{{{
class1
class2
}}}
may be better under some circumstances since it doesn't mess around with the HTML and doesn't assume that you always want to set the class (sometimes you might want to change the 'style' attribute).
-- Matt