[IMP] report_webkit: some improvements, notably the use of "makoed" jinja like email_template
and shortcut to extend evaluation context bzr revid: nicolas.vanhoren@openerp.com-20130226153524-ny52u94g2l4qtcwk
This commit is contained in:
commit
108d5f1d6c
|
@ -36,5 +36,6 @@ import webkit_report
|
|||
import ir_report
|
||||
import wizard
|
||||
import convert
|
||||
import report
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -55,7 +55,7 @@
|
|||
<body style="border:0; margin: 0;" onload="subst()">
|
||||
<table class="header" style="border-bottom: 0px solid black; width: 100%">
|
||||
<tr>
|
||||
<td>${helper.embed_company_logo()|n}</td>
|
||||
<td>${helper.embed_company_logo()|safe}</td>
|
||||
<td style="text-align:right"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
@ -63,21 +63,21 @@
|
|||
<td style="text-align:right"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>${company.partner_id.name |entity}</td>
|
||||
<td>${company.partner_id.name}</td>
|
||||
<td/>
|
||||
</tr>
|
||||
<tr>
|
||||
<td >${company.partner_id.street or ''|entity}</td>
|
||||
<td >${company.partner_id.street or ''}</td>
|
||||
<td/>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Phone: ${company.partner_id.phone or ''|entity} </td>
|
||||
<td>Phone: ${company.partner_id.phone or ''} </td>
|
||||
<td/>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Mail: ${company.partner_id.email or ''|entity}<br/></td>
|
||||
<td>Mail: ${company.partner_id.email or ''}<br/></td>
|
||||
</tr>
|
||||
</table> ${_debug or ''|n} </body>
|
||||
</table> ${_debug or ''|safe} </body>
|
||||
</html>]]>
|
||||
</field>
|
||||
<field eval="55.0" name="margin_top"/>
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
|
||||
import webkit_report_demo
|
|
@ -11,6 +11,7 @@
|
|||
% endfor
|
||||
</ul>
|
||||
|
||||
<p>The administrator name is: ${admin_name}</p>
|
||||
<p>If this report does not contain headers, it is because you have a badly compiled wkhtmltopdf. Consider installing
|
||||
the static version distributed on the official web site: <a href="https://code.google.com/p/wkhtmltopdf/">https://code.google.com/p/wkhtmltopdf/</a>.</p>
|
||||
</body>
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
|
||||
|
||||
from openerp.addons.report_webkit.webkit_report import webkit_report_extender
|
||||
from openerp import SUPERUSER_ID
|
||||
|
||||
@webkit_report_extender("report_webkit.webkit_demo_report")
|
||||
def extend_demo(pool, cr, uid, localcontext, context):
|
||||
admin = pool.get("res.users").browse(cr, uid, SUPERUSER_ID, context)
|
||||
localcontext.update({
|
||||
"admin_name": admin.name,
|
||||
})
|
|
@ -38,10 +38,6 @@ import tempfile
|
|||
import time
|
||||
import logging
|
||||
|
||||
from mako.template import Template
|
||||
from mako.lookup import TemplateLookup
|
||||
from mako import exceptions
|
||||
|
||||
from openerp import netsvc
|
||||
from openerp import pooler
|
||||
from report_helper import WebKitHelper
|
||||
|
@ -50,16 +46,72 @@ from openerp import addons
|
|||
from openerp import tools
|
||||
from openerp.tools.translate import _
|
||||
from openerp.osv.osv import except_osv
|
||||
from urllib import urlencode, quote as quote
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
try:
|
||||
# We use a jinja2 sandboxed environment to render mako templates.
|
||||
# Note that the rendering does not cover all the mako syntax, in particular
|
||||
# arbitrary Python statements are not accepted, and not all expressions are
|
||||
# allowed: only "public" attributes (not starting with '_') of objects may
|
||||
# be accessed.
|
||||
# This is done on purpose: it prevents incidental or malicious execution of
|
||||
# Python code that may break the security of the server.
|
||||
from jinja2.sandbox import SandboxedEnvironment
|
||||
mako_template_env = SandboxedEnvironment(
|
||||
block_start_string="<%",
|
||||
block_end_string="%>",
|
||||
variable_start_string="${",
|
||||
variable_end_string="}",
|
||||
comment_start_string="<%doc>",
|
||||
comment_end_string="</%doc>",
|
||||
line_statement_prefix="%",
|
||||
line_comment_prefix="##",
|
||||
trim_blocks=True, # do not output newline after blocks
|
||||
autoescape=True, # XML/HTML automatic escaping
|
||||
)
|
||||
mako_template_env.globals.update({
|
||||
'str': str,
|
||||
'quote': quote,
|
||||
'urlencode': urlencode,
|
||||
})
|
||||
except ImportError:
|
||||
_logger.warning("jinja2 not available, templating features will not work!")
|
||||
|
||||
def mako_template(text):
|
||||
"""Build a Mako template.
|
||||
|
||||
This template uses UTF-8 encoding
|
||||
"""
|
||||
tmp_lookup = TemplateLookup() #we need it in order to allow inclusion and inheritance
|
||||
return Template(text, input_encoding='utf-8', output_encoding='utf-8', lookup=tmp_lookup)
|
||||
|
||||
return mako_template_env.from_string(text)
|
||||
|
||||
_extender_functions = {}
|
||||
|
||||
def webkit_report_extender(report_name):
|
||||
"""
|
||||
A decorator to define functions to extend the context used in a template rendering.
|
||||
report_name must be the xml id of the desired report (it is mandatory to indicate the
|
||||
module in that xml id).
|
||||
|
||||
The given function will be called at the creation of the report. The following arguments
|
||||
will be passed to it (in this order):
|
||||
- pool The model pool.
|
||||
- cr The cursor.
|
||||
- uid The user id.
|
||||
- localcontext The context given to the template engine to render the templates for the
|
||||
current report. This is the context that should be modified.
|
||||
- context The OpenERP context.
|
||||
"""
|
||||
def fct1(fct):
|
||||
lst = _extender_functions.get(report_name)
|
||||
if not lst:
|
||||
lst = []
|
||||
_extender_functions[report_name] = lst
|
||||
lst.append(fct)
|
||||
return fct
|
||||
return fct1
|
||||
|
||||
class WebKitParser(report_sxw):
|
||||
"""Custom class that use webkit to render HTML reports
|
||||
|
@ -201,6 +253,17 @@ class WebKitParser(report_sxw):
|
|||
def create_single_pdf(self, cursor, uid, ids, data, report_xml, context=None):
|
||||
"""generate the PDF"""
|
||||
|
||||
# just try to find an xml id for the report
|
||||
cr = cursor
|
||||
import openerp.pooler as pooler
|
||||
pool = pooler.get_pool(cr.dbname)
|
||||
found_xml_ids = pool.get("ir.model.data").search(cr, uid, [["model", "=", "ir.actions.report.xml"], \
|
||||
["res_id", "=", report_xml.id]], context=context)
|
||||
xml_id = None
|
||||
if found_xml_ids:
|
||||
xml_id = pool.get("ir.model.data").read(cr, uid, found_xml_ids[0], ["module", "name"])
|
||||
xml_id = "%s.%s" % (xml_id["module"], xml_id["name"])
|
||||
|
||||
if context is None:
|
||||
context={}
|
||||
htmls = []
|
||||
|
@ -242,64 +305,57 @@ class WebKitParser(report_sxw):
|
|||
if not css :
|
||||
css = ''
|
||||
|
||||
#default_filters=['unicode', 'entity'] can be used to set global filter
|
||||
body_mako_tpl = mako_template(template)
|
||||
helper = WebKitHelper(cursor, uid, report_xml.id, context)
|
||||
self.parser_instance.localcontext['helper'] = helper
|
||||
self.parser_instance.localcontext['css'] = css
|
||||
self.parser_instance.localcontext['_'] = self.translate_call
|
||||
|
||||
# apply extender functions
|
||||
additional = {}
|
||||
if xml_id in _extender_functions:
|
||||
for fct in _extender_functions[xml_id]:
|
||||
fct(pool, cr, uid, self.parser_instance.localcontext, context)
|
||||
|
||||
if report_xml.precise_mode:
|
||||
for obj in objs:
|
||||
self.parser_instance.localcontext['objects'] = [obj]
|
||||
ctx = dict(self.parser_instance.localcontext)
|
||||
for obj in self.parser_instance.localcontext['objects']:
|
||||
ctx['objects'] = [obj]
|
||||
try :
|
||||
html = body_mako_tpl.render(helper=helper,
|
||||
css=css,
|
||||
_=self.translate_call,
|
||||
**self.parser_instance.localcontext)
|
||||
html = body_mako_tpl.render(dict(ctx))
|
||||
htmls.append(html)
|
||||
except Exception:
|
||||
msg = exceptions.text_error_template().render()
|
||||
except Exception, e:
|
||||
msg = u"%s" % e
|
||||
_logger.error(msg)
|
||||
raise except_osv(_('Webkit render!'), msg)
|
||||
else:
|
||||
try :
|
||||
html = body_mako_tpl.render(helper=helper,
|
||||
css=css,
|
||||
_=self.translate_call,
|
||||
**self.parser_instance.localcontext)
|
||||
html = body_mako_tpl.render(dict(self.parser_instance.localcontext))
|
||||
htmls.append(html)
|
||||
except Exception:
|
||||
msg = exceptions.text_error_template().render()
|
||||
msg = u"%s" % e
|
||||
_logger.error(msg)
|
||||
raise except_osv(_('Webkit render!'), msg)
|
||||
head_mako_tpl = mako_template(header)
|
||||
try :
|
||||
head = head_mako_tpl.render(helper=helper,
|
||||
css=css,
|
||||
_=self.translate_call,
|
||||
_debug=False,
|
||||
**self.parser_instance.localcontext)
|
||||
except Exception:
|
||||
raise except_osv(_('Webkit render!'),
|
||||
exceptions.text_error_template().render())
|
||||
head = head_mako_tpl.render(dict(self.parser_instance.localcontext, _debug=False))
|
||||
except Exception, e:
|
||||
raise except_osv(_('Webkit render!'), u"%s" % e)
|
||||
foot = False
|
||||
if footer :
|
||||
foot_mako_tpl = mako_template(footer)
|
||||
try :
|
||||
foot = foot_mako_tpl.render(helper=helper,
|
||||
css=css,
|
||||
_=self.translate_call,
|
||||
**self.parser_instance.localcontext)
|
||||
except:
|
||||
msg = exceptions.text_error_template().render()
|
||||
foot = foot_mako_tpl.render(dict({},
|
||||
**self.parser_instance.localcontext))
|
||||
except Exception, e:
|
||||
msg = u"%s" % e
|
||||
_logger.error(msg)
|
||||
raise except_osv(_('Webkit render!'), msg)
|
||||
if report_xml.webkit_debug :
|
||||
try :
|
||||
deb = head_mako_tpl.render(helper=helper,
|
||||
css=css,
|
||||
_debug=tools.ustr("\n".join(htmls)),
|
||||
_=self.translate_call,
|
||||
**self.parser_instance.localcontext)
|
||||
except Exception:
|
||||
msg = exceptions.text_error_template().render()
|
||||
deb = head_mako_tpl.render(dict(self.parser_instance.localcontext, _debug=tools.ustr("\n".join(htmls))))
|
||||
except Exception, e:
|
||||
msg = u"%s" % e
|
||||
_logger.error(msg)
|
||||
raise except_osv(_('Webkit render!'), msg)
|
||||
return (deb, 'html')
|
||||
|
|
Loading…
Reference in New Issue