Hypy
Hypy, means hypertext in python, it's yet another template engine for python. Released under the MIT licence.It's more than a "proof of concept" but can contains some bugs ;-)
The idea : Why could'nt we make html like python code ?
If you, like me, edit your html in an text-editor and indent it to be human-readable. Hypy is for you : it will simplify your work ; you'll not need anymore to close the tags.
Features
- lightweight (1 file of 400 lines of code)
- compile template : If template is a file : it's compiled to bytecode (pyc file)
- Able to produce xml (xhtml) or non-xml strings
- blocks : if-else / for / capture
- inheritance (masterpage/childpage)
- unicode support
Future
- perhaps a strip method ?!
Example
A simple example of template :@html:Remarks:
@head:
@title:
the title of the page
@body:
@div id="main":
# this is a comment
the content of the page
- "markup block" ends with ":"
- the rest is "text content"
- the html structure is defined by indentations
- comment starts with an '#', but a comment must be a line ! (it's not possible to append a comment to a line)
it will generate :
<html>Note :
<head>
<title>the title of the page</title>
</head>
<body>
<div id="main">the content of the page</div>
</body>
</html>
- it's very easy to make xhtml like that.
It will be better if we introduce some dynamics in the template ;-)
@html:Remarks :
@head:
@title:
the title of the page
@body:
@div id="main":
hello ${name}
@for id,val in list:
@li:
${id} for ${val}
- ${...} is the pattern for substitution (like string.template in py2.4). Call the parse method, with a dict {"name" : "jo", "list": [ (1, "one"), (2, "two") ]}
- @ is used to mark "python code" (like decorators in py2.4)
- it will generate some <li>...</li> for each tuple in the list
It's possible to use "nested for" too, like this :
@html:
@head:
@title:
the title of the page
@body:
@div id="main":
@for list in lists:
@for id,val in list:
@li:
${id} for ${val}
And it's possible to add conditions too
@html:Remarks :
@head:
@title:
the title of the page
@body:
@div id="main":
@if len(list)>2:
@for id,name in list:
@li:
${id} for ${name}
@else:
nope
- "if/else" and "for" are exactly like python clauses
- there is a @capture block too (see the example in the code)
<html>Remarks :
<head>
<title>the title of the page</title>
</head>
<body>
<div id="main">
@if len(list)>2:
@for id,name in list:
<li>${id} for ${name}</li>
</div >
</body>
</html>
- thus, it's possible to render "non-xhtml strings".
- And it's possible to mix the two methods too !!!!
Inheritance
Hypy can have templates ("child-template") which herit from another template ("masterpage") (It works only for files templates )Here is a masterpage template (let's name it as "mama.tpl"):
<html>Note
<head>
<title>${title}</title>
</head>
<body>
<div id="menu">
@declare menu:
no default menu
</div >
<div id="main">
@declare content:
no default content
</div >
</body>
</html>
- We use the @declare keyword to create sections for inheritance. They will be replaced by the content of "define section" of a child template.
@master mama.tpl:Remarks
@define menu:
@if isAuthentified:
@for href,title in list:
<a href="${href}">${title}</a>
@define content:
hello world, here is hypy ;-)
- @master define the name of the masterpage which should be, in this case, in the same folder as this child template
- @master and @define's should be "initial sections"
- In this case, if isAuthentified is true, it will display links, else it will display "no default menu"
- If "@define content" was not here, it will display "no defaut content"
This should render something like that :
<html>
<head>
<title>the title</title>
</head>
<body>
<div id="menu">
<a href="http1">url1</a>
<a href="http2">url2</a>
</div >
<div id="main">
hello world, here is hypy ;-)
</div >
</body>
</html>
Unicode support
Hypy can manage encodings. You'll have just to define what encoding you use in your template, like you do in your python sources.# -*- coding: utf-8 -*-The template will be treated as unicode. The parse method will return UTF-8 by default. But you can specify it, like that :
html:
head:
title:
thé tîtle ôf the pägè
body:
here is the ${msg}
your_dict = { "msg" : u"hÿpÿ" }Note
print parse( "your_teplate.tpl", your_dict, out="cp1252" )
- if you set None to "out", it will return unicode.
- you'll have to pass your "content text" in unicode !
Download
Try hypy.py v0.6... but don't forget : it may contains bugs ...25/02/06: v0.6
- SYNTAX CHANGE : "html:" -> "@html:"
- pyc file renamed to avoid import of real python module
- take care of indent !!!
21/02/06: v0.5
- full unicode support
- change licence GPLv2 -> MIT
20/02/06 v0.4:
- "cache", by default:true ... put at false, to dev (for dynamic)
- recompile template (if needed) should work now on win32 (use st_mtime now)
- work with "tabs" now too, count() redone, (thx to david'bgk)
- work now as module (__builtins__ trouble)
- import pyc works now on win32 (sys.path modified)
19/02/06 v0.3:
- real capture
- inheritance with @master/@define(child) and @declare(masterpage) sections (ONLY IN FILES)
- compile() method !
- @else clause for @if !
- raise errors on bad indentation of "real block" (it's possible to bad indent on text content)
18/02/06 v0.2:
- compile template file to pyc (python bytecode)
- nested for
- "for" works now on his own dico (not locals() anymore)
17/02/06 v0.1+:
- parse don't need a dict anymore
- the first markup don't need to be at the beginning anymore
16/02/06 v0.1:
- initial release