| 245 | | |
|---|
| 246 | | |
|---|
| 247 | | class cgitemplate: |
|---|
| 248 | | """ simple cgi engine for serving templess templates |
|---|
| 249 | | """ |
|---|
| 250 | | |
|---|
| 251 | | def __init__(self, template, content_type='text/html; charset=UTF-8', |
|---|
| 252 | | error_template='templates/cgierror.html', headers={}): |
|---|
| 253 | | self.template = template |
|---|
| 254 | | self.content_type = content_type |
|---|
| 255 | | self.error_template = error_template |
|---|
| 256 | | self.headers = headers |
|---|
| 257 | | |
|---|
| 258 | | def render(self, context): |
|---|
| 259 | | """ render and output the document |
|---|
| 260 | | |
|---|
| 261 | | this also prints the Content-Type header, if you want it to print |
|---|
| 262 | | other headers use the headers arg of the constructor |
|---|
| 263 | | """ |
|---|
| 264 | | if not context.has_key('footer'): |
|---|
| 265 | | context['footer'] = __footer__ |
|---|
| 266 | | try: |
|---|
| 267 | | fp = open(self.template) |
|---|
| 268 | | try: |
|---|
| 269 | | t = template(fp) |
|---|
| 270 | | ret = t.render_to_string(context, html=True) |
|---|
| 271 | | finally: |
|---|
| 272 | | fp.close() |
|---|
| 273 | | assert type(ret) == str |
|---|
| 274 | | self.print_output(self.content_type, ret) |
|---|
| 275 | | except: |
|---|
| 276 | | import sys |
|---|
| 277 | | exc, e, tb = sys.exc_info() |
|---|
| 278 | | ret = self.handle_exception(exc, e, tb) |
|---|
| 279 | | |
|---|
| 280 | | def handle_exception(self, exc, e, tb): |
|---|
| 281 | | """ internal method that generates and prints an exception page |
|---|
| 282 | | """ |
|---|
| 283 | | from traceback import format_tb |
|---|
| 284 | | tblist = format_tb(tb) |
|---|
| 285 | | fp = open(self.error_template) |
|---|
| 286 | | try: |
|---|
| 287 | | t = template(fp) |
|---|
| 288 | | context = { |
|---|
| 289 | | 'exception': str(exc), |
|---|
| 290 | | 'message': str(e), |
|---|
| 291 | | 'traceback': '\n'.join(tblist), |
|---|
| 292 | | 'tblist': [{'line': str(l)} for l in tblist], |
|---|
| 293 | | 'footer': __footer__, |
|---|
| 294 | | } |
|---|
| 295 | | ret = t.render_to_string(context, html=True) |
|---|
| 296 | | finally: |
|---|
| 297 | | fp.close() |
|---|
| 298 | | self.print_output('text/html; charset=UTF-8', ret) |
|---|
| 299 | | |
|---|
| 300 | | def print_output(self, content_type, body): |
|---|
| 301 | | """ actually print the output |
|---|
| 302 | | """ |
|---|
| 303 | | print 'Content-Type: %s' % content_type |
|---|
| 304 | | for kv in self.headers.items(): |
|---|
| 305 | | print '%s: %s' % kv |
|---|
| 306 | | print |
|---|
| 307 | | print body |
|---|