diff --git a/addons/report/controllers/main.py b/addons/report/controllers/main.py index c6bc13d38f8e64e4df7e9105de5f6f75c6b35417..01992d64c602dd05a3bcc01011d32088cbfb6db3 100644 --- a/addons/report/controllers/main.py +++ b/addons/report/controllers/main.py @@ -50,7 +50,12 @@ class ReportController(Controller): if data.get('options'): options_data = simplejson.loads(data['options']) if data.get('context'): - context.update(simplejson.loads(data['context'])) + # Ignore 'lang' here, because the context in data is the one from the webclient *but* if + # the user explicitely wants to change the lang, this mechanism overwrites it. + data_context = simplejson.loads(data['context']) + if data_context.get('lang'): + del data_context['lang'] + context.update(data_context) if converter == 'html': html = report_obj.get_html(cr, uid, docids, reportname, data=options_data, context=context) diff --git a/addons/report/models/report.py b/addons/report/models/report.py index 176356880637cf7fc3aeee1bb1632e20360eed86..3e4bbb069e19bd98cd38ea42e17db012896da752 100644 --- a/addons/report/models/report.py +++ b/addons/report/models/report.py @@ -34,10 +34,8 @@ import lxml.html import cStringIO import subprocess from distutils.version import LooseVersion -try: - from pyPdf import PdfFileWriter, PdfFileReader -except ImportError: - PdfFileWriter = PdfFileReader = None +from functools import partial +from pyPdf import PdfFileWriter, PdfFileReader _logger = logging.getLogger(__name__) @@ -71,23 +69,6 @@ class Report(osv.Model): public_user = None - MINIMAL_HTML_PAGE = """ -<base href="{base_url}"> -<!DOCTYPE html> -<html style="height: 0;"> - <head> - <link href="/report/static/src/css/reset.min.css" rel="stylesheet"/> - <link href="/web/static/lib/bootstrap/css/bootstrap.css" rel="stylesheet"/> - <link href="/website/static/src/css/website.css" rel="stylesheet"/> - <link href="/web/static/lib/fontawesome/css/font-awesome.css" rel="stylesheet"/> - <style type='text/css'>{css}</style> - {subst} - </head> - <body class="container" onload="subst()"> - {body} - </body> -</html>""" - #-------------------------------------------------------------------------- # Extension of ir_ui_view.render with arguments frequently used in reports #-------------------------------------------------------------------------- @@ -134,6 +115,7 @@ class Report(osv.Model): website = None if request and hasattr(request, 'website'): website = request.website + context.update(translatable=context.get('lang') != request.website.default_lang_code) values.update( time=time, translate_doc=translate_doc, @@ -198,6 +180,10 @@ class Report(osv.Model): footerhtml = [] base_url = self.pool['ir.config_parameter'].get_param(cr, uid, 'web.base.url') + # Minimal page renderer + view_obj = self.pool['ir.ui.view'] + render_minimal = partial(view_obj.render, cr, uid, 'report.minimal_layout', context=context) + # The received html report must be simplified. We convert it in a xml tree # in order to extract headers, bodies and footers. try: @@ -208,12 +194,12 @@ class Report(osv.Model): for node in root.xpath("//div[@class='header']"): body = lxml.html.tostring(node) - header = self.MINIMAL_HTML_PAGE.format(css=css, subst=subst, body=body, base_url=base_url) + header = render_minimal(dict(css=css, subst=subst, body=body, base_url=base_url)) headerhtml.append(header) for node in root.xpath("//div[@class='footer']"): body = lxml.html.tostring(node) - footer = self.MINIMAL_HTML_PAGE.format(css=css, subst=subst, body=body, base_url=base_url) + footer = render_minimal(dict(css=css, subst=subst, body=body, base_url=base_url)) footerhtml.append(footer) for node in root.xpath("//div[@class='page']"): @@ -230,7 +216,7 @@ class Report(osv.Model): reportid = False body = lxml.html.tostring(node) - reportcontent = self.MINIMAL_HTML_PAGE.format(css=css, subst='', body=body, base_url=base_url) + reportcontent = render_minimal(dict(css=css, subst='', body=body, base_url=base_url)) # FIXME: imo the best way to extract record id from html reports is by using the # qweb branding. As website editor is not yet splitted in a module independant from diff --git a/addons/report/views/layouts.xml b/addons/report/views/layouts.xml index f9c0ea7ef73017dbf0cf6f1dfd1e3dab4703283e..f12f7672d21f695938a170161ebed8cc4d748019 100644 --- a/addons/report/views/layouts.xml +++ b/addons/report/views/layouts.xml @@ -1,55 +1,35 @@ <?xml version="1.0" encoding="utf-8"?> <openerp> <data> -<template id="html_container"> - <!DOCTYPE html> - <html t-att-lang="lang and lang.replace('_', '-')" - t-att-data-editable="'1' if editable else None" - t-att-data-view-xmlid="xmlid if editable else None" - t-att-data-main-object="repr(main_object) if editable else None" - t-att-data-report-margin-top="data_report_margin_top if data_report_margin_top else None" - t-att-data-report-header-spacing="data_report_header_spacing if data_report_header_spacing else None" - t-att-data-report-dpi="data_report_dpi if data_report_dpi else None" - t-att-data-oe-company-name="res_company.name"> - <head> - <meta name="viewport" content="width=device-width, initial-scale=1"/> - - <t t-if="main_object and 'website_meta_title' in main_object"> - <t t-set="title" t-value="main_object.website_meta_title"/> - </t> - <t t-if="not title and main_object and 'name' in main_object"> - <t t-set="additional_title" t-value="main_object.name"/> - </t> - <meta name="description" t-att-value="main_object and 'website_meta_description' in main_object - and main_object.website_meta_description or website_meta_description"/> - <meta name="keywords" t-att-value="main_object and 'website_meta_keywords' in main_object - and main_object.website_meta_keywords or website_meta_keywords"/> - - <link id="bootstrap_css" rel='stylesheet' href='/web/static/lib/bootstrap/css/bootstrap.css' t-ignore="true"/> - <link rel="stylesheet" type="text/css" href='/website/static/src/css/website.css'/> - <style type="text/css"> - <t t-call="report.style"/> - </style> - - <link rel='stylesheet' href='/web/static/lib/fontawesome/css/font-awesome.css'/> +<template id="layout" inherit_id="web.layout" primary="True"> + <!-- Add report attributes --> + <xpath expr="//html" position="attributes"> + <attribute name="t-att-data-report-margin-top">data_report_margin_top if data_report_margin_top else None</attribute> + <attribute name="t-att-data-report-header-spacing">data_report_header_spacing if data_report_header_spacing else None</attribute> + <attribute name="t-att-data-report-dpi">data_report_dpi if data_report_dpi else None</attribute> + </xpath> + <!-- Add report style --> + <xpath expr="//head" position="inside"> + <link href="/web/static/lib/bootstrap/css/bootstrap.css" rel="stylesheet"/> + <link href="/website/static/src/css/website.css" rel="stylesheet"/> + <link href="/web/static/lib/fontawesome/css/font-awesome.css" rel="stylesheet"/> + <style type="text/css"> + <t t-call="report.style"/> + </style> + </xpath> + <!-- Remove conflicting style --> + <xpath expr="//head/link[@href='/web/static/src/css/full.css']" position="replace"></xpath> + <!-- Correct view inheritance --> + <xpath expr="//t[@t-name='web.layout']" position="attributes"> + <attribute name="t-name">report.layout</attribute> + </xpath> +</template> - <script type="text/javascript" src="/web/static/lib/es5-shim/es5-shim.min.js"></script> - <script type="text/javascript" src="/web/static/lib/underscore/underscore.js"></script> - <script type="text/javascript" src="/web/static/lib/underscore.string/lib/underscore.string.js"></script> - <script type="text/javascript" src="/web/static/lib/jquery/jquery.js"></script> - <script type="text/javascript" src="/web/static/lib/bootstrap/js/bootstrap.js"></script> - <script type="text/javascript" src="/web/static/lib/qweb/qweb2.js"></script> - <script type="text/javascript" src="/web/static/src/js/openerpframework.js"></script> - <script type="text/javascript" src="/website/static/src/js/website.js"></script> - <script t-if="not translatable" type="text/javascript" src="/website/static/src/js/website.snippets.animation.js"></script> - <t t-raw="head or ''" name='layout_head'/> - </head> - <body class="container"> - <div id="wrapwrap"> - <t t-raw="0"/> - </div> - </body> - </html> +<template id="html_container"> + <t t-set="body_classname" t-value="'container'"/> + <t t-call="report.layout"> + <t t-raw="0"/> + </t> </template> <template id="style"> @@ -164,5 +144,23 @@ <t t-raw="0" /> </template> +<template id="minimal_layout"> + <t t-raw="'<base href=%s>' % base_url"/> + <!DOCTYPE html> + <html style="height: 0;"> + <head> + <link href="/report/static/src/css/reset.min.css" rel="stylesheet"/> + <link href="/web/static/lib/bootstrap/css/bootstrap.css" rel="stylesheet"/> + <link href="/website/static/src/css/website.css" rel="stylesheet"/> + <link href="/web/static/lib/fontawesome/css/font-awesome.css" rel="stylesheet"/> + <style type='text/css'><t t-raw="css"/></style> + <t t-raw="subst"/> + </head> + <body class="container" onload="subst()"> + <t t-raw="body"/> + </body> + </html> +</template> + </data> </openerp> diff --git a/addons/sale/views/report_saleorder.xml b/addons/sale/views/report_saleorder.xml index 5c198c635a3bbd23b87f93aae96af5ad743318b8..a6771823f5563f234f00cf4f4d0f60d0f182f92e 100644 --- a/addons/sale/views/report_saleorder.xml +++ b/addons/sale/views/report_saleorder.xml @@ -65,7 +65,7 @@ <tbody class="sale_tbody"> <tr t-foreach="o.order_line" t-as="l"> <td> - <span t-field="l.name"/> + <span t-field="l.name"/> </td> <td> <span t-esc="', '.join(map(lambda x: x.name, l.tax_id))"/> diff --git a/addons/website/views/website_templates.xml b/addons/website/views/website_templates.xml index 4a37ae180fc734bba257c7d1bc795f67367079b2..4b31b086dbd110309b7a814c30f345826e93caeb 100644 --- a/addons/website/views/website_templates.xml +++ b/addons/website/views/website_templates.xml @@ -57,7 +57,7 @@ <template id="layout" name="Main layout"><!DOCTYPE html> <html t-att-lang="lang and lang.replace('_', '-')" - t-att-data-website-id="website.id if editable else None" + t-att-data-website-id="website.id if editable and website else None" t-att-data-editable="'1' if editable else None" t-att-data-editable-no-editor="editable_no_editor or None" t-att-data-translatable="'1' if translatable else None" @@ -82,10 +82,10 @@ and main_object.website_meta_keywords or website_meta_keywords"/> <title><t t-esc="title"/></title> - <t t-set="languages" t-value="website.get_languages()"/> - <t t-if="request.website_multilang"> + <t t-set="languages" t-value="website.get_languages() if website else None"/> + <t t-if="request and request.website_multilang"> <t t-foreach="languages" t-as="lg"> - <t t-set="force_lang" t-value="lg[0] if lg[0] != website.default_lang_code else None"/> + <t t-set="force_lang" t-value="lg[0] if website and lg[0] != website.default_lang_code else None"/> <link rel="alternate" t-att-href="url_for(request.httprequest.path + '?' + keep_query(), lang=force_lang)" t-att-hreflang="lg[0].replace('_', '-').lower()" /> </t> </t> @@ -150,7 +150,7 @@ </div> </footer> </div> - <t t-if="website.google_analytics_key"> + <t t-if="website and website.google_analytics_key"> <script> (function(b,o,i,l,e,r){b.GoogleAnalyticsObject=l;b[l]||(b[l]= function(){(b[l].q=b[l].q||[]).push(arguments)});b[l].l=+new Date; diff --git a/addons/website_livechat/views/website_livechat.xml b/addons/website_livechat/views/website_livechat.xml index 374e0d5dd161d586e2087ce888139bb3035d6514..ef6b2a978fffeec97dc3d649e26ccacd280f9df9 100644 --- a/addons/website_livechat/views/website_livechat.xml +++ b/addons/website_livechat/views/website_livechat.xml @@ -4,7 +4,7 @@ <template id="header" inherit_id="website.layout" name="LiveChat Snippet"> <xpath expr="//body" position="inside"> - <t t-if="website.channel_id"> + <t t-if="website and website.channel_id"> <t t-raw="website.channel_id.script"/> </t> </xpath> diff --git a/addons/website_report/views/layouts.xml b/addons/website_report/views/layouts.xml index 97297a66e10c6c12a2022427300e04afe0d8dc07..c1cc3b4936527ca14e3d2bbbb04d236bc498bcee 100644 --- a/addons/website_report/views/layouts.xml +++ b/addons/website_report/views/layouts.xml @@ -1,92 +1,47 @@ <?xml version="1.0" encoding="utf-8"?> <openerp> <data> -<template id="editor_head" inherit_id="report.html_container" name="Editor" groups="base.group_website_publisher"> + +<template id="layout" inherit_id="website.layout" primary="True"> + <!-- Add report attributes --> <xpath expr="//html" position="attributes"> - <attribute name="t-att-data-website-id">website.id if editable and website else None</attribute> - <attribute name="t-att-data-translatable">'1' if translatable else None</attribute> + <attribute name="t-att-data-report-margin-top">data_report_margin_top if data_report_margin_top else None</attribute> + <attribute name="t-att-data-report-header-spacing">data_report_header_spacing if data_report_header_spacing else None</attribute> + <attribute name="t-att-data-report-dpi">data_report_dpi if data_report_dpi else None</attribute> </xpath> - - <xpath expr="//body" position="attributes"> - <attribute name="style">padding-top: 51px;</attribute> + <!-- Add report style --> + <xpath expr="//head" position="inside"> + <style type="text/css"> + <t t-call="report.style"/> + </style> </xpath> - <xpath expr="//body" position="inside"> - <div id="website-top-navbar-placeholder" class="navbar navbar-inverse navbar-fixed-top hidden-xs"> - <div class="navbar-header"> - <form class="navbar-form navbar-left"> - <button type="button" class="btn btn-primary">Edit</button> - </form> - </div> - <div class="collapse navbar-collapse navbar-edit-collapse"> - <ul class="nav navbar-nav navbar-right"> - <li><a href="#" onclick="return false;"><i class="fa fa-mobile" title="Mobile preview"/></a></li> - <li class="divider-vertical"/> - <li><a href="#" onclick="return false;"><span title="Promote page on the web">Promote</span></a></li> - <li class="dropdown"> - <a href="#" onclick="return false;">Content <span class="caret"/></a> - </li> - <li class="dropdown"> - <a href="#" onclick="return false;">Customize <span class="caret"/></a> - </li> - <li class="dropdown"> - <a href="#" onclick="return false;">Help <span class="caret"/></a> - </li> - </ul> - </div> - </div> + <xpath expr="//body" position="attributes"> + <attribute name="class">container</attribute> </xpath> - <xpath expr='//t[@name="layout_head"]' position="before"> - <link rel='stylesheet' href='/website/static/src/css/snippets.css'/> - <link rel='stylesheet' href='/website/static/src/css/editor.css'/> - - - <link rel="stylesheet" href="/web/static/lib/select2/select2.css"/> - <link rel="stylesheet" href="/website/static/lib/select2-bootstrap-css/select2-bootstrap.css"/> - <link rel='stylesheet' href="/web/static/lib/jquery.ui/css/smoothness/jquery-ui-1.9.1.custom.css"/> - - <script type="text/javascript" src="/web/static/lib/select2/select2.js"></script> - <script type="text/javascript" src="/web/static/lib/ckeditor/ckeditor.js"></script> - <script type="text/javascript" src="/website/static/lib/ace/ace.js"></script> - <script type="text/javascript" src="/website/static/lib/vkbeautify/vkbeautify.0.99.00.beta.js"></script> - <script type="text/javascript" src="/web/static/lib/jquery.ui/js/jquery-ui-1.9.1.custom.js"></script> - <!-- mutation observers shim backed by mutation events (8 < IE < 11, Safari < 6, FF < 14, Chrome < 17) --> - <script type="text/javascript" src="/website/static/lib//jquery.mjs.nestedSortable/jquery.mjs.nestedSortable.js"></script> - <script type="text/javascript" src="/website/static/lib/MutationObservers/test/sidetable.js"></script> - <script type="text/javascript" src='/website/static/lib/nearest/jquery.nearest.js'></script> - <script type="text/javascript" src="/website/static/lib/MutationObservers/MutationObserver.js"></script> - - <script type="text/javascript" src="/website/static/lib/jquery.placeholder/jquery.placeholder.js"></script> - - <script type="text/javascript" src="/website/static/src/js/website.editor.js"></script> - <script type="text/javascript" src="/website/static/src/js/website.menu.js"></script> - <script type="text/javascript" src="/website/static/src/js/website.editor.newpage.js"></script> <!-- groups="base.group_website_designer" --> - <script type="text/javascript" src="/website/static/src/js/website.contentMenu.js"></script> <!-- groups="base.group_website_designer" --> - <script type="text/javascript" src="/website/static/src/js/website.mobile.js"></script> - <script type="text/javascript" src="/website/static/src/js/website.seo.js"></script> - <script type="text/javascript" src="/website/static/src/js/website.snippets.editor.js"></script> - <script type="text/javascript" src="/website/static/src/js/website.ace.js"></script> - <script type="text/javascript" src="/website/static/src/js/website.translator.js"></script> - <script type="text/javascript" src="/website/static/src/js/jQuery.transfo.js"></script> + <xpath expr="//header" position="replace"/> + <xpath expr="//footer" position="replace"> + <ul class="list-inline js_language_selector mt16" t-if="(request and request.website_multilang and len(languages) > 1) or (website and editable)"> + <li t-foreach="languages" t-as="lg"> + <a t-att-href="url_for(request.httprequest.path + '?' + keep_query(), lang=lg[0])" + t-att-data-default-lang="editable and 'true' if website and lg[0] == website.default_lang_code else None"> + <t t-esc="lg[1].split('/').pop()"/> + </a> + </li> + <li groups="base.group_website_publisher"> + <t t-set="url_return" t-value="url_for('', '[lang]') + '?' + keep_query()"/> + <a t-attf-href="/web#action=base.action_view_base_language_install&website_id=#{website.id if website else ''}&url_return=#{url_return}"> + <i class="fa fa-plus-circle"/> + Add a language... + </a> + </li> + </ul> </xpath> +</template> - <xpath expr='//body[@class="container"]/div[@id="wrapwrap"]' position="before"> - <t t-set="languages" t-value="website.get_languages() if website else None"/> - <t t-if="languages"> - <ul class="list-inline js_language_selector mt16" t-if="(len(languages) > 1 or editable)"> - <li t-foreach="languages" t-as="lg"> - <a t-att-href="url_for('', lang=lg[0]) + '?' + keep_query()" - t-att-data-default-lang="editable and 'true' if lg[0] == website.default_lang_code else None"> - <t t-esc="lg[1].split('/').pop()"/> - </a> - </li> - <li groups="base.group_website_publisher"> - <t t-set="url_return" t-value="url_for('', '[lang]') + '?' + keep_query()"/> - <a t-attf-href="/web#action=base.action_view_base_language_install&website_id=#{website.id}&url_return=#{url_return}"> - <i class="fa fa-plus-circle"/> - Add a language... - </a> - </li> - </ul> +<template id="website_html_container" inherit_id="report.html_container"> + <xpath expr="//t[@t-call='report.layout']" position="replace"> + <t t-call="website_report.layout"> + <t t-raw="0"/> </t> </xpath> </template>