HTML.py - a Python module to easily generate HTML tables and lists

HTML.py has been developed to easily generate HTML code for tables and lists in Python scripts. This is mostly convenient to generate reports in HTML or simple web applications in lightweight frameworks such as CherryPy.

There are already quite a few similar solutions for Python, either HTML generators or templating engines (see links at the end of this article). Most of them are very powerful but quite complex for simple cases. HTML.py is useful when you need to generate simple HTML code without requiring to learn a templating language. Furthermore, while some HTML generators provide a comprehensive object-oriented model of HTML, HTML.py is meant to translate Python objects to HTML as easily as possible.

Download

Click on the attached file below at the bottom of this page.

License

Cecill: open-source, GPL compatible.


How to use HTML.py

Basic principles

The HTML module provides two different interfaces: classes (Table, List, ...) and functions with similar names in lowercase (table, list, ...). Functions simply translate Python data to HTML source code in a string, while classes are a representation of data which may be modified in place and rendered as HTML code when needed. For simple tasks functions are easier to use, while classes provide more flexibility.


HTML Tables

Basically, an HTML table is stored as a list of rows. Each row is itself a list of cells. Each cell is a Python string or any object which may be rendered as a string using str().

So the easiest way to create a HTML table is to use a list of lists:

import HTML
table_data = [
        ['Last name',   'First name',   'Age'],
        ['Smith',       'John',         30],
        ['Carpenter',   'Jack',         47],
        ['Johnson',     'Paul',         62],
    ]
htmlcode = HTML.table(table_data)
print htmlcode

A header row may be specified: it will appear in bold in browsers

table_data = [
        ['Smith',       'John',         30],
        ['Carpenter',   'Jack',         47],
        ['Johnson',     'Paul',         62],
    ]

htmlcode = HTML.table(table_data,
    header_row=['Last name',   'First name',   'Age'])
print htmlcode

You may also create a Table object and add rows one by one. Its "rows" attribute is a list which can be modified in place. When the table is complete, convert the Table object to a string using str() to get the HTML code:

t = HTML.Table(header_row=['x', 'square(x)', 'cube(x)'])
for x in range(1,10):
    t.rows.append([x, x*x, x*x*x])
htmlcode = str(t)
print htmlcode

Rows may be any iterable (list, tuple, ...) including a generator. This is useful to save memory when generating a large table.

def gen_rows(i):
    'rows generator'
    for x in range(1,i):
        yield [x, x*x, x*x*x]
htmlcode = HTML.table(gen_rows(10), header_row=['x', 'square(x)', 'cube(x)'])
print htmlcode

To choose a specific background color for a cell, use a TableCell object:

HTML_COLORS = ['Black', 'Green', 'Silver', 'Lime', 'Gray', 'Olive', 'White',
    'Maroon', 'Navy', 'Red', 'Blue', 'Purple', 'Teal', 'Fuchsia', 'Aqua']
t = HTML.Table(header_row=['Name', 'Color'])
for colorname in HTML_COLORS:
    colored_cell = HTML.TableCell(' ', bgcolor=colorname)
    t.rows.append([colorname, colored_cell])
htmlcode = str(t)
print htmlcode

Here is an example of how HTML.py can be used to generate a test report with colors for successes, failures and errors:

# dictionary of test results, indexed by test id:
test_results = {
        'test 1': 'success',
        'test 2': 'failure',
        'test 3': 'success',
        'test 4': 'error',
    }
# dict of colors for each result:
result_colors = {
        'success':      'lime',
        'failure':      'red',
        'error':        'yellow',
    }
t = HTML.Table(header_row=['Test', 'Result'])
for test_id in sorted(test_results):
    # create the colored cell:
    color = result_colors[test_results[test_id]]
    colored_result = HTML.TableCell(test_results[test_id], bgcolor=color)
    # append the row with two cells:
    t.rows.append([test_id, colored_result])
htmlcode = str(t)
print htmlcode

HTML Lists

a HTML list (with bullets) may simply be built from a Python list of strings:

a_list = ['john', 'paul', 'jack']
htmlcode = HTML.list(a_list)
print htmlcode

It is easy to change it into a numbered (ordered) list:

htmlcode = HTML.list(a_list, ordered=True)
print htmlcode

Lines of a list may also be added one by one, when using the List class. Its "lines" attribute can be modified in place:

html_list = HTML.List()
for i in range(1,10):
    html_list.lines.append('square(%d) = %d' % (i, i*i))
htmlcode = str(html_list)
print htmlcode

To save memory, a large list may also be built from a generator:

def gen_lines(i):
    'lines generator'
    for x in range(1,i):
        yield 'square(%d) = %d' % (x, x*x)
htmlcode = HTML.list(gen_lines(10))
print htmlcode

HTML Links

How to create a link:

htmlcode = HTML.link('Decalage website', 'http://www.decalage.info')
print htmlcode

HTML.py tutorial

All the examples above may be tested using the script HTML_tutorial.py provided with HTML.py.


Alternatives

If HTML.py does not suit your needs, there are quite a few other solutions to generate HTML from Python:

HTML generators:

Templating engines:

 

AttachmentSize
HTML.py-0.04.zip30.41 KB

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

HTML.py - adding header_styles and td_styles parameters

Hallo,
I,ve needed to do some tables, so I used your modul HTML but changed it a bit. Now it's quite easy to make tables with various styles:

t = HTML.Table(header_row= ['č.b.', 'jméno', 'podíl', 'první vhodné datum', 'druhé vhodné datum', 'podpis'],
header_styles=('width: 3%', 'width: 25%', 'width: 5%', 'width: 12%', 'width: 12%', 'width: 15%' ),
td_styles= ('text-align: right', '', 'text-align: right', '', '', '' ))
for byt, podil, jmeno in naj:
t.rows.append([byt, jmeno, podil, '', ''])
htmlcode = str(t). Are you interested?

Kind regards Michal

Added column styles, width and alignment

Michal, I've improved HTML.py thanks to your ideas and code proposal. The Table class in HTML.py 0.04 provides new attributes to set width, alignment and style for each column. The implementation is slightly different from the one you proposed in order to keep it simple and extensible, but it should provide the same results.

At first I wanted to use the simple <COL> tags according to HTML 4.01 specs, but after some time I realized I was hitting one of the oldest and trickiest bugs in Mozilla and Firefox!: https://bugzilla.mozilla.org/show_bug.cgi?id=915

That's why in the end column width and styles are added to each cell, in order to accomodate with browser bugs...

HTMLGen

Hallo,

i use your HTML.py module and it works very well. Now I've tried to use HTMLGen from this website
http://www.python.org/ftp/python/contrib-09-Dec-1999/Network/

But it uses regex and and regsub. I think these modules are old an no longer supported in the actual python (2.6). Do you have a running version of HTMLGen??

Regards,
Albert

HTMLGen

Indeed HTMLGen is quite old and it has not been updated since 2001. It would have to be modified to run with latest Python versions (2.5+), at least by using the re module instead of regex/regsub. Sorry, I haven't found any fixed version so far.

Philippe.

HTML.py

Hi,

Just testing out HTML.py on a mac. So far works great - nice and simple.

Feature request 'image' class -I tend to add images to tables, beyond that it has everything I need.

Right now to get the desired output I would add my image to a cell in the table class and string replace the html output

old image name:

replacePrefix_myPicture.jpg_replaceSuffix

loop over the html created by HTML.py

newHtml = oldHtml.replace('replacePrefix_', '')

This will work but is a little clumsy - having an image class, like the link class would be great.

thanks,
cl

Images in table cells

Hi cl,

I'm not exactly sure what you need to do, but at least you may simply use any "raw" HTML inside each cell. For example if you want to insert an image, you may use something like this:

mytable.rows.append(['image 1', '<img src="img1.jpg">'])

Of course it would be easy to create a new function similar to HTML.link in order to create image tags. I'll think of it for the next version of HTML.py.

Thank you for your feedback,

Philippe.

Creating several pages in a single document

Hi,

I want to create a html document such that it has several pages of data. How do I create different pages within the same document? What is the method for that?

Or is it necessary to create several docs and then link it?

Several pages in a single HTML document

A basic HTML document can only be one page. However, you may use JavaScript and CSS to change the displayed content when the user clicks on a link or a tab, giving the illusion of several pages in one (see this example). Another possibility is to have all the text in the same page and choose which part to display according to the URL thanks to PHP (see that example). Google is your friend.

Few Queries

Hi,

Is there any option for changing the font style and font color of the text that gets displayed in the HTML sheet?

Is there any scope for alignment of text data which is passed into the HTML sheet using the HTML.list() method? Say a particular header needs to be center aligned.

Also, can linking within the various sections of text in the same page be done using HTML.link() method? If not, how can it be achieved?

a few answers

There are many options to set font styles and colors in various places of a HTML page, but this question is more about HTML in general than HTML.py itself. Look for "html font" and "html css" in your favorite search engine, there are many useful tutorials to start with.

You may use styles in HTML.py objects when they have a "style" attribute, or else using the "attribs" attribute. For example:

a_list = ['john', 'paul', 'jack']
htmlcode = HTML.list(a_list, attribs={'style': 'font-family: Helvetica, Arial, sans-serif'})

To answer your second question, you may add a style attribute to a list so that it is centered:

htmlcode = HTML.list(a_list, attribs={'style': 'text-align: center'})

To create links which point to other sections in the same page, just use anchors with a name attribute, and then links such as "#name". Example:

<a name="section1">SECTION 1</a>
...
<a href="#section1">link to section 1</a>

Regarding HTML.link

Hi,

I have used HTML.py to create several HTML sheets. However, one sheet among it acts like the Main Page which has links to the rest of the sheets. The rest of the sheets apart from the main sheet are inside a sub-folder. Thus, the main folder consists of the Main Page and the sub-folder.

The links in the Main Page direct to the various other pages really well when the Python code is compiled on Linux. However, when just the output alone was checked on Windows platform, the links do not work.

The HTML.link method seems to be system specific. Can you please suggest what can be done in this regard so that the links work in any platform?

Is there any alternative apart from using the actual hyperlinks using href and name? That would be more of HTML coding than Python

Thank you

HTML links

HTML.link just creates HTML links with the URLs you provide, so the syntax should not depend on the OS. Please send me an e-mail at decalage(a)laposte.net with an example of your code, I'll see what the exact issue is.