Skip to content
Lingfeng edited this page Apr 21, 2015 · 2 revisions

Introduction

PyH is a very powerful and compact python module that lets you write HTML content from within your python program. Hard-coding plain HTML into your python code is boring and can make your code completely unreadable. Plus, once you'll have a look at the source of the HTML file, it won't be readable either. PyH gives you a nice solution for all of this. PyH lets you code your web page like a GUI!

Features

  • Automatic formating of HTML tags
  • High customizability
  • full CSS and Javascript awareness
  • Automatic tag closure
  • Object-oriented coding of HTML

How to install PyH

Download the latest version of pyh from the Download tab or directly from here PyH-0.1.tar.gz, unpack it in your working directory or in your system's python directory, usually /usr/lib/pythonX.X/site-packages or anywhere visible by the environment variable $PYTHONPATH:

$ wget http://pyh.googlecode.com/files/PyH-0.1.tar.gz
$ tar xvzf PyH-0.1.tar.gz
$ cd PyH-0.1
$ sudo python setup.py install

If you do not have root privileges, simply copy the file PyH-0.1/pyh.py into your project's directory. If you're running a RPM-based distribution you can also use rpm binaries and install them with

$ wget http://pyh.googlecode.com/files/PyH-0.1-1.noarch.rpm
$ sudo rpm -ivh PyH-0.1-1.noarch.rpm

Quick example

The following python code snipet

from pyh import *
page = PyH('My wonderful PyH page')
page.addCSS('myStylesheet1.css', 'myStylesheet2.css')
page.addJS('myJavascript1.js', 'myJavascript2.js')
page << h1('My big title', cl='center')
page << div(cl='myCSSclass1 myCSSclass2', id='myDiv1') << p('I love PyH!', id='myP1')
mydiv2 = page << div(id='myDiv2')
mydiv2 << h2('A smaller title') + p('Followed by a paragraph.')
page << div(id='myDiv3')
page.myDiv3.attributes['cl'] = 'myCSSclass3'
page.myDiv3 << p('Another paragraph')
page.printOut()

will generate the following html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>My wonderful PyH page</title>
<link href="myStylesheet1.css" type="text/css" rel="stylesheet" />
<link href="myStylesheet2.css" type="text/css" rel="stylesheet" />
<script src="myJavascript1.js" type="text/javascript"></script>
<script src="myJavascript2.js" type="text/javascript"></script>
</head>
<body>
<h1 class="center">My big title</h1>
<div id="myDiv1" class="myCSSclass1 myCSSclass2">
<p id="myP1">I love PyH!</p>
</div>
<div id="myDiv2">
<h2>A smaller title</h2>
<p>Followed by a paragraph.</p>
</div>
<div id="myDiv3" class="myCSSclass3">
<p>Another paragraph</p>
</div>
</body>
</html>

Basic manual

The pyh.py module can be imported as such :

>>> from pyh import *

The Tag objects

HTML tags can be generated by calling the function of the same name. The HTML tag <tag> is invoked via the class tag() :

>>> mydiv = div()
>>> mydiv.render()
'<div></div>'

Tag attributes are passed as keyword parameters to the functions. The keyword is the same name as the attribute except for the attribute class which is replaced by cl. The content of the tag (text or sub-tags) is passed a non-keyword parameter :

>>> mydiv = div('My content', cl='myCSSclass1 myCSSclass2', id='myCSSid1')
>>> mydiv.render()
'<div class="myCSSclass1 myCSSclass2" id="myCSSid1">
My content
</div>'

Other tags can also be passed as content :

>>> mydiv = div(p('My paragraph.'), cl='myCSSclass1 myCSSclass2', id='myCSSid1')
>>> mydiv.render()
'<div class="myCSSclass1 myCSSclass2" id="myCSSid1">
<p>My paragraph</p>
</div>'

Once a tag object has been created, its HTML attributes can be modified by accessing its attributes member which is a dictionary :

>>> mydiv = div()
>>> mydiv.attributes['id'] = 'myCSSid'
>>> mydiv.render()
'<div id="myCSSid"></div>\n'

Tag can be concatenated by the use of the simple + operator :

>>> twoDivs = div() + div()
>>> twoDivs.render()
'<div></div>
<div></div>'

Tags can be included inside higher level tags either by passing them as non-keywords arguments as explained above or thanks to the << operator. The operation returns the last included tag :

>>> myDiv = div(id='myTopLevelDiv')
>>> myPar = myDiv << div(id='myInnerDiv') << p(id='myPar') 
>>> myPar << span('My first span') + span('My second span')
>>> myDiv.render()
'<div id="myTopLevelDiv">
<div id="myInnerDiv">
<p id="myPar">
<span>My first span</span><span>My second span</span>
</p>
</div>
</div>'

Once a tag has been included into another one it can still be accessed as a member of the upper-level tag. The name of the member is the id of the tag if it is specified. Otherwise it is the name of the tag if it is the first tag of its kind, 'tag_001' if its the second and so on :

>>> myDiv = div()
>>> myDiv << span(id='myspan')
>>> myDiv.myspan << 'content1'
>>> myDiv << span()
>>> myDiv.span << 'content2'
>>> myDiv << span()
>>> myDiv.span_001 << 'content3'
>>> myDiv.render()
'<div>
<span id="myspan">content1</span>
<span>content2</span>
<span>content3</span>
</div>'

Build a web page

The highest-level object is the PyH object. It allows to create a self-contained HTML page with CSS and javascript components. The first thing to do in order to create a web page is to instanciate the PyH object:

from pyh import *
page = PyH('My wonderful PyH page')

You can then add your CSS stylesheets and javascript files as such :

page.addCSS('myStylesheet1.css', 'myStylesheet2.css')
page.addJS('myJavascript1.js', 'myJavascript2.js')

Note that that they can be included at anytime in you python script (e.g. depending on your content, allowing to include only used scripts and stylesheets). You can now start building your page :

page << h1('My big title!', cl='myCSSclass')
page << div(id='mySubtitleDiv') << h2('My sub-title')
maindiv = page << div(id='myMainDiv')
maindiv << h3('A smaller title') + p('followed by a small paragraph')
maindiv << p('Main paragraph ', style='color:red;') << a('a link', href='http://alink')
maindiv << span('hehe', onclick='myJavaScriptFcn(); return false;')
maindiv << br()
maindiv << img(src='mypicture.jpg')
page << div(id='myFooter') << span('My footer')

Then, to output your HTML page to a file or to a browser if your script is being run by a web server :

page.printOut()

The output of this script will be

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>My wonderful PyH page</title>
<link href="myStylesheet1.css" type="text/css" rel="stylesheet" />
<link href="myStylesheet2.css" type="text/css" rel="stylesheet" />
<script src="myJavascript1.js" type="text/javascript"></script>
<script src="myJavascript2.js" type="text/javascript"></script>
</head>
<body>
<h1 class="myCSSclass">My big title!</h1>
<div id="mySubtitleDiv"><h2>My sub-title</h2></div>
<div id="myMainDiv">
<h3>A smaller title</h3>
<p>followed by a small paragraph</p>
<p style="color:red;">Main paragraph <a href="http://alink">a link</a>
<span onclick="myJavaScriptFcn(); return false;">hehe</span><br />
<img src="mypicture.jpg" />
</div>
<div id="myFooter"><span>My footer</span>
</div>
</body>
</html>

Build tables

You can combine python's and pyh's full power to generate HTML tables very efficiently. Creating a simple 4 by 4 table is a cakewalk:

page = PyH('My wonderful PyH page')
page << h2('Most compact way to build a 4 by 4 table')
page << table() << tr(td('1') + td('2')) + tr(td('3') + td('4'))
page << h2('Another way to build a 4 by 4 table')
mytab = page << table()
tr1 = mytab << tr()
tr1 << td('1') + td('2')
tr2 = mytab << tr()
tr2 << td('3') + td('4')
page.printOut()

The code will generate the following HTML (all headers have been removed for clarity) :

<h2>Most compact way to build a 4 by 4 table</h2>
<table>
<tr>
<td>1</td><td>2</td>
</tr><tr>
<td>3</td><td>4</td>
</tr>
</table>
<h2>Another way to build a 4 by 4 table</h2>
<table>
<tr>
<td>1</td><td>2</td>
</tr><tr>
<td>3</td><td>4</td>
</tr>
</table>

Now if you want to create large automatized table, e.g. from a database you can go

mytab = page << table()
for i in range(nrows):
    mytr = mytab << tr()
    for j in range(ncols):
        mytr << td('Row %i, column %j' % (i, j))

which will produce a i by j array.