RML with TurboGears 2

You should download the ZIP archive of the entire project to get the full code listing and to try it out.


(4.0 KB, 23 Mar 2010, md5 checksum=5c10cf7bc44ba77ff6dc4a405bffe554)


Report Markup Language™ is an XML-style language created by ReportLab that describes the precise look of a printed page. This sample application shows how you can use the RML2PDF conversion library from within Turbogears 2.

RML is commercial software which is part of the ReportLab PLUS package. You will need to create a user account to download a trial version of ReportLab PLUS.

Integrate Report Markup Language into your TurboGears project and add great looking dynamic PDF output to your website. This sample project shows you how - it's a simple demonstration of how to merge an RML 'template' with user-submitted, variable content - in this case the user's name - and convert the output into a PDF which is returned to the browser.

Its easy to expand on the principles shown here. Use Genshi, or another templating engine, to include conditionals and loops, and create complex PDF documents with any kind of dynamic content.

Code overview

Here's a walkthrough of the most interesting parts of the sample application. The downloadable archive also contains a README file with installation instructions and commented code.

The project serves up a simple HTML form. The user enters their name and clicks the 'submit' button, and this calls a function in the RootController class which uses the Genshi templating engine to substitute the name entered in the form in the relevant part of our RML template ('hello.rml')

from genshi.template import TemplateLoader
loader = TemplateLoader(os.getcwd() + '/rptlabrmlsample/templates/')
rml = loader.load('hello.rml')
return rml.generate(name=personName).render('xml')

Next, create a CStringIO buffer and send the rml we've created to the rml2pdf.go() function. The resulting PDF is returned as a byte array.

from rlextra.rml2pdf import rml2pdf
rml = mergeRML(q)  #merge the template and variables
buf = cStringIO.StringIO()
rml2pdf.go(rml, outputFileName=buf) #creates the pdf
pdfData = buf.read()

The only remaining task is to return the PDF to the user. Set the appropriate properties in the response object, and return the contents of the buffer.

response.headers["Content-Type"] = "application/pdf"
response.headers["Content-disposition"] = "attachment; filename=report.pdf"
response.headers["Content-Length"] = len(a)
return a