473,387 Members | 3,810 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

Using a decorator for generic html templates

Hello all,

While studying some of the templating systems available for Python,
I've come up with an idea to implement templates using decorators. The
following code snippet runs in Python 2.3; a few 2.4 only extensions
are shown as comments. Please note that I have shamelessly copied the
trim function from PEP 257, because it's needed to have the strings
properly formatted.

============================
#
# HTML templating decorator
# Carlos Ribeiro
# ca********@gmail.com
# http://pythonnotes.blogspot.com
#

import sys

def trim(docstring):
# shamelessly taken from PEP 257:
# http://www.python.org/peps/pep-0257.html
if not docstring:
return ''
# Convert tabs to spaces (following the normal Python rules)
# and split into a list of lines:
lines = docstring.expandtabs().splitlines()
# Determine minimum indentation (first line doesn't count):
indent = sys.maxint
for line in lines[1:]:
stripped = line.lstrip()
if stripped:
indent = min(indent, len(line) - len(stripped))
# Remove indentation (first line is special):
trimmed = [lines[0].strip()]
if indent < sys.maxint:
for line in lines[1:]:
trimmed.append(line[indent:].rstrip())
# Strip off trailing and leading blank lines:
while trimmed and not trimmed[-1]:
trimmed.pop()
while trimmed and not trimmed[0]:
trimmed.pop(0)
# Return a single string:
return '\n'.join(trimmed)

def raw_html_template(func):
"""
Transforms a simple raw html template function into a function that
returns the __doc__ string. Non-significant spaces are removed,
making the resulting output indent correctly.
"""
def new_func(args):
return func.__doc__

#new_func.func_name = func.func_name # 2.4 only
return new_func

class Root:
#@raw_html_template # 2.4 only
def index(self):
"""
<html>
<body>
<h1>Hello World!</h1>
</body>
</html>
"""

index = raw_html_template(index) #2.3 only

A simple test run is:
r = Root()
r.index() '\n <html>\n <body>\n <h1>Hello
World!</h1>\n </body>\n </html>\n '


============================
Comments about this technique:

1) It abuses the doc string to obtain the desired effect. While some
may not like it as a hack, it's actually very clean; the resulting
code looks really nice without extra clutter.

2) More advanced decorators can be supported. For example, embedded
tags can be pre-processed by the decorator, either at "decorating
time" (when the decorator function is run) or at runtime (by means of
special code in the decorated function).

3) Methods that interleave Python code and raw HTML code are *much*
more difficult to handle. I don't have enough knowledge to deem them
impossible, but that's my best guess now. *If* someone is brave enough
to try it, my guess is that it has to rely very heavily on
introspection and low-level disassembly hacks. Not for the faint of
heart... and too [asm|C|INTERCAL]-ish for my taste :-)

4) Another approach that could be possibly taken is to use a metaclass
to control the decoration of all methods that have only docstrings and
no code. Using introspection, the constructor could check all methods
and decorate the ones that need it, building the new object
accordingly.

5) In real world applications, performance may be a concern. I don't
know if the decorator is applied every time a new object instance is
created, or if a caching mechanism of some type is used. If the
decorator is run everytime a new instance is about to be created, then
a different approach is needed, because many web application
frameworks rely on short lived objects to represent stuff such as
actual page handlers. That's where a metaclass approach could be more
useful.

6) Last, I don't know if the trim() function is available through some
of the standard libraries, and I have no idea upon where to look after
it. But it would be a good idea to call the standard implementation
instead of repeating the code here. (btw, the implementation has a
small bug: it leaves some extra space at the last line that should be
removed).
--
Carlos Ribeiro
Consultoria em Projetos
blog: http://rascunhosrotos.blogspot.com
blog: http://pythonnotes.blogspot.com
mail: ca********@gmail.com
mail: ca********@yahoo.com
Jul 18 '05 #1
0 1359

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

11
by: Ville Vainio | last post by:
It might just be that @decorator might not be all that bad. When you look at code that uses it it's not that ugly after all. A lot of the furor about this is probably because it happened so...
6
by: Michele Simionato | last post by:
could ildg wrote: > I think decorator is a function which return a function, is this right? > e.g. The decorator below if from http://www.python.org/peps/pep-0318.html#id1. > > def...
4
by: Pat Turner | last post by:
Hi, I have some XML like this: <family> <person name="bob"> <father ref="../../person" /> </person> <person name="charlie"> <child ref="../../person" />
7
by: Allan Bruce | last post by:
I have had a look through the FAQ and found that if I am using a class template then I need an argument list. I have tried to add this but it is not quite working - i.e. it doesnt compile. My...
1
by: Einar Høst | last post by:
Hi, I'm writing a data layer for an app my company is developing. I'm thinking about wrapping up the basic data access object in two decorator objects: one to provide error checking on...
28
by: steve yee | last post by:
i think c should adapt c++ template standard, as well as namespace. if so, c can replace c++ in many cases.
2
by: nachu | last post by:
hello, 1. i would require help on how to design or how well the templates for "generic project management " can be designed the s/w used: ...
9
by: Tyno Gendo | last post by:
Hi I'm trying to learn patterns, which I hope to use in my PHP code, although I'm finding it hard to get any real impression of how patterns fit in properly, I've done the following test code...
2
by: Joe Strout | last post by:
On Nov 13, 2008, at 11:15 AM, J. Cliff Dyer wrote: Right, though the hasattr() check I put in my version of this approach takes care of that. Now THAT is something that hadn't occurred to...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.