|
PyMeldA simple, lightweight system for manipulating HTML (and XML, informally)
using a Pythonic object model. Features:
Quick overview A >>> from PyMeld import Meld >>> xhtml = '''<html><body> ... <textarea id="message" rows="2" wrap="off">Type your message.</textarea> ... </body></html>''' >>> page = Meld(xhtml) # Create a Meld object from XHTML. >>> print page.message # Access an element within the document. <textarea id="message" rows="2" wrap="off">Type your message.</textarea> >>> print page.message.rows # Access an attribute of an element. 2 >>> page.message = "New message." # Change the content of an element. >>> page.message.rows = 4 # Change an attribute value. >>> del page.message.wrap # Delete an attribute. >>> print page # Print the resulting page. <html><body> <textarea id="message" rows="4">New message.</textarea> </body></html> So the program logic and the HTML are completely separated - a graphical
designer can design the HTML in a visual XHTML editor, without needing to
deal with any non-standard syntax or non-standard attribute names. The
program code knows nothing about XML or HTML - it just deals with objects and
attributes like any other piece of Python code. Populating an HTML form with
a record from a database is a one-liner (using the Real-world example: Here's a data-driven example populating a table from a data source, basing the table on sample data put in by the page designer. Note that in the real world the HTML would normally be a larger page read from an external file, keeping the data and presentation separate, and the data would come from an external source like an RDBMS. The HTML could be full of styles, images, anything you like and it would all work just the same.
>>> xhtml = '''<html><table id="people">
... <tr id="header"><th>Name</th><th>Age</th></tr>
... <tr id="row"><td id="name">Example name</td><td id="age">21</td></tr>
... </table></html>'''
>>> doc = Meld(xhtml)
>>> templateRow = doc.row.clone() # Take a copy of the template row, then
>>> del doc.row # delete it to make way for the real rows.
>>> for name, age in [("Richie", 30), ("Dave", 39), ("John", 78)]:
... newRow = templateRow.clone()
... newRow.name = name
... newRow.age = age
... doc.people += newRow
>>> print re.sub(r'</tr>\s*', '</tr>\n', str(doc)) # Prettify the output
<html><table id="people">
<tr id="header"><th>Name</th><th>Age</th></tr>
<tr id="row"><td id="name">Richie</td><td id="age">30</td></tr>
<tr id="row"><td id="name">Dave</td><td id="age">39</td></tr>
<tr id="row"><td id="name">John</td><td id="age">78</td></tr>
</table></html>
Note that if you were going to subsequently manipulate the table, using
PyMeld or JavaScript for instance, you'd need to rename each As the example shows, the Shortcut: the % operator Using the
>>> for name, age in [("Richie", 30), ("Dave", 39), ("John", 78)]:
... doc.people += templateRow % (name, age)
The
>>> print templateRow % {'name': 'Frances', 'age': 39}
<tr id="row"><td id="name">Frances</td><td id="age">39</td></tr>
The Note that these examples are written for clarity rather than performance, and
don't necessarily scale very well - using Element content When you refer to a named element in a document, you get a Meld object representing that whole element:
>>> page = Meld('<html><span id="x">Hello world</span></html>')
>>> print page.x
<span id="x">Hello world</span>
If you just want to get the content of the element as string, use the
>>> print page.x._content Hello world You can also assign to >>> page.x._content = "Hello again" >>> print page <html><span id="x">Hello again</span></html> >>> page.x = "Goodbye" >>> print page <html><span id="x">Goodbye</span></html> The only time that you need to assign to >>> x = page.x >>> x._content = "I'm back" >>> print page <html><span id="x">I'm back</span></html> Saying Version and license This is version 2.1.3 of PyMeld, Copyright (c) 2005 Entrian Solutions. It is released under the terms of the Sleepycat License (see the top of PyMeld.py), which allows Open Source products to freely redistribute it in source or binary form. Commercial licensing is available for a fee; contact richie@entrian.com for more information. Version 1.0 had a different API which is now deceased. If you need advice on upgrading your code to use the new API (which should be trivial), or you need a copy of PyMeld 1.0, please contact richie@entrian.com.
|