taglib demo page

About taglib

The last iteration of this website was written using mod_wsgi, and consisted of

  1. a set of page classes (because I’m a creative genius, the base class is called Page); and
  2. a tag-generation library (which, for the reason stated above, I’ve come to think of as taglib).
The tag library is heavily inspired by an internal library used at my workplace, but owes no code whatsoever to it—that library is written in PHP (not my favourite language) and suffers from various problems, chiefly that it’s old, predating good language support for OOP, and horrendously complicated (in places) to modify.

Still, I rather liked the idea, so I decided to see what I could accomplish in that vein with an afternoon’s Python work. Apparently, I decided that what I could accomplish was worth keeping, and I use it here and there in this website—mostly for fun and because it lets me make shorthand tags (<entry> for <div class="entry"> being a simple example). Anyone who’s worked there and looked at it knows that complex_tag is aptly named indeed…

It can do more useful things, however, like generating elements on the fly, dynamically populating them (e.g. from a database), and so forth.

The next section of this page is rather inane and simply shows a few examples of taglib in action. There’s also a source listing for this page. Both of these really refer to the older version; what you see was rendered by Django and not by taglib.

Preliminaries

Here’s some tag soup, with some non-ASCII characters thrown in. It may be unsurprising that a guy named ‘Häggholm’ should build a library that focuses strictly on Unicode strings… We’ll be parsing this stuff into an object-oriented structure.

This has to be valid XML, except that no root element is required.

Strictly speaking, that means it can’t be real tag soup.

Here’s a rather differently generated paragraph.

Here’s another one.

Fun with sequences

Let’s have a list! Note that this is filled with a dict, which is unordered. You may want some kind of ordered map for this one…

  1. Trois!
  2. Deux!
  3. Un!

Obviously, we can make ’em unordered.

And of course tables are good, too

#1#2#3#4
#1#2#3#4
Just a table caption
herearesomewords
sittinginatable
withheadandfoot

Source listing

# coding=utf8

from __future__ import with_statement
import codecs
from htpage.page import *
from taglib import tags
from page import phPage


class Taglibdemo(phPage):
    """Page class demonstrating how this stuff works."""

    @makepage
    def main(self):
        """Invoked by the Page class to fill in the contents.

        This is an example of the Abstract Method pattern, to give it a name
        fancier than its workings.
        """

        soup = u"""<h1>taglib demo page</h1>
            <entry>
                <h2>About taglib</h2>
                <p>
                This website was written using <tt>mod_wsgi</tt>, and
                consists of
                <ol>
                    <li>a set of page classes (because I’m a creative genius,
                        the base class is called <tt>Page</tt>); and</li>
                    <li>a tag-generation library (which, for the reason stated
                        above, I’ve come to think of as
                        <q><tt>taglib</tt></q>).</li>
                </ol>
                The tag library is <em>heavily</em> inspired by an internal
                library used at my workplace, but owes no code whatsoever to
                it—that library is written in PHP (not my favourite language)
                and suffers from various problems, chiefly that it’s old,
                predating good language support for OOP, and horrendously
                complicated (in places) to modify.
                </p>
                <p>
                Still, I rather liked the idea, so I decided to see what I
                could accomplish in that vein with an afternoon’s Python work.
                Apparently, I decided that what I could accomplish was worth
                keeping, and I use it here and there in this website—mostly
                for fun and because it lets me make shorthand tags
                (<tt>&lt;entry&gt;</tt> for
                <tt>&lt;div&nbsp;class="entry"&gt;</tt>
                being a simple example). Anyone who’s worked there and
                looked at it knows that <tt>complex_tag</tt> is aptly named
                indeed…
                </p>
                <p>
                It can do more useful things, however, like generating elements
                on the fly, dynamically populating them (e.g. from a database),
                and so forth.
                </p>
                <p>
                The <a href="#example">next section</a> of this page is rather
                inane and simply shows a few examples of <tt>taglib</tt> in
                action. There’s also a <a href="#source">source listing</a>
                <em>for</em> this page.
                </p>
            </entry>

            <entry id="my_entry">
                <h2 id="#example">Preliminaries</h2>
                <p>
                    Here’s some tag soup, with some non-ASCII characters thrown
                    in. It may be unsurprising that a guy named ‘Häggholm’
                    should build a library that focuses strictly on Unicode
                    strings… We’ll be parsing this stuff into an
                    object-oriented structure.
                </p>
                <p style="font-weight: bold;">
                    This has to be valid XML, except that no root element is
                    required.
                </p>
                <p class="small">
                    Strictly speaking, that means it <em>can’t</em> be real
                    <q>tag soup</q>.
                </p>
            </entry>

            <entry>
                <h2>Fun with sequences</h2>
                <p>
                    Let’s have a list! Note that this is filled with a
                    <tt>dict</tt>, which is unordered. You may want some kind of
                    ordered map for this one…
                </p>
                <ol id="french_list" />
                <p>
                    <em>Obviously</em>, we can make ’em unordered.
                </p>
                <ul id="item_list" />
            </entry>

            <entry>
                <h2>And of course tables are good, too</h2>
                <table id="the_table" class="tabular" />
            </entry>

            <entry>
                <h2 id="source">Source listing</h2>
                <textarea id="sourcecode" />
            </entry>
        """
        ts = self.parse(soup)

        ts['my_entry'].content += [
            tags.p(u'Here’s a rather differently generated paragraph.'),
            tags.p(u'Here’s another one.'),
            tags.ul(['And', 'a', 'list'])
        ]

        ts['french_list'].content = {'one': 'Un!', 'two': 'Deux!',
                                         'three': 'Trois!'}
        ts['item_list'].content = ['Towel', 'Sub-etha-thingamajig', 'Guide']

        # Why the three levels of nesting for a list? Well, a <table> can
        # have more than one <tbody>, so the content is an sequence of
        # tbodies; each a sequence of rows; each a sequence of cells.
        ts['the_table'].caption = 'Just a table caption'
        ts['the_table'].head = ['#1', '#2', '#3', '#4']
        ts['the_table'].foot = ts.dom['the_table'].head
        ts['the_table'].content = [[
            ['here', 'are', 'some', 'words'],
            ['sitting', 'in', 'a', 'table'],
            ['with', 'head', 'and', 'foot']
        ]]

        def fix(l):
            return l.replace(u'&', u'&amp;').replace(u'>', u'&gt;').replace(u'<', u'&lt;')

        with codecs.open(self.meta.dir+'/taglibdemo.py', 'r', 'utf-8') as f:
            ts['sourcecode'].content = u''.join(f.readlines())

        # Inline CSS isn't nice, but for now...
        self.css = "#sourcecode { width: 100%; height: 40em; }"

        return ts
Now in my blog:
RSS feed LiveJournal blog Show me more!