If you benefit from web2py hope you feel encouraged to pay it forward by contributing back to society in whatever form you choose!

27 Dec 09 edit to protect script blocks

When web2py renders a template, it leaves extra blank lines in the output, making the html harder to read, and looking, well, generated. Removing those lines improves the appearance of the html.

The following snippet filters out those excess lines. Place it in a controller.py file to filter the output of that controller, or in a models.py file to filter the entire application.

import re
def filter(d):
    if not isinstance(d,dict):  d = d()
    return re.compile(r'\n([ \t]+\n)+').sub('\n',response.render(d))
response._caller=filter

A slightly more complex approach leaves <pre> and <script> blocks untouched:

import re
def  save_block(match):
    s = match.group()
    if  s.startswith('<'): return s
    return '/n'

def filter(d):
    if not isinstance(d,dict):  d = d()
    pat = '\n([ \t]+\n)+'             # match empty lines that start with spaces
    pat += '|(?s)<script.*?</script'  # OR script blocks 
    pat += '|(?s)<pre.*?</pre'        # OR pre blocks 
    cpat = re.compile(pat)
    return cpat.sub(save_block, response.render(d))

response._caller=filter

Note: This is said to mess up flash.

Related slices

Comments (9)

  • Login to post



  • 0
    thadeusb 15 years ago
    Alternatively if you have utidy installed... def utidy(d): if not isinstance(d, dict): d = d() import tidy pretty = dict(output_xhtml=1, add_xml_decl=1, indent=1, tidy_mark=1, wrap=0, ) if True: #if you want to compress pretty['indent'] = 0 return tidy.parseString(response.render(d), **pretty) response._caller = utidy

  • 0
    aleksdj 15 years ago
    Many thanks for both solutions. This result in a better debug and presentation output of html.

  • 0
    aleksdj 15 years ago
    Another note: using this output render reduce the size of html considerably, otherwise the html output its 2x in size approximately for a 1000 lines of html code. (that is bandwidth and cost consumption)

  • 0
    thadeusb 14 years ago
    it also messes up javascript. How to add to this? I have been playing around but no luck.

  • 0
    kbochert 14 years ago
    To leave both pre blocks and script blocks untouched Try: def save_block(match): s = match.group() if s.startswith('<'): return s return '\n' def filter(d): if not isinstance(d,dict): d = d() cpat = re.compile(r'\n([ \t]+\n)+|(?s)
    .*
    |(?s)') return cpat.sub(save_block, response.render(d)) response._caller=filter
show more comments

Hosting graciously provided by:
Python Anywhere