From d7cdac5aa82cf5961af132079286cdac509933e8 Mon Sep 17 00:00:00 2001 From: David Beal Date: Thu, 7 Sep 2017 13:16:21 +0200 Subject: [PATCH 01/28] ADD module mail_inline_css --- mail_inline_css/README.rst | 101 +++++++++++++++++++++++++++++ mail_inline_css/__init__.py | 1 + mail_inline_css/__manifest__.py | 18 +++++ mail_inline_css/models/__init__.py | 1 + mail_inline_css/models/mail.py | 24 +++++++ 5 files changed, 145 insertions(+) create mode 100644 mail_inline_css/README.rst create mode 100644 mail_inline_css/__init__.py create mode 100644 mail_inline_css/__manifest__.py create mode 100644 mail_inline_css/models/__init__.py create mode 100644 mail_inline_css/models/mail.py diff --git a/mail_inline_css/README.rst b/mail_inline_css/README.rst new file mode 100644 index 00000000..b76d1dfe --- /dev/null +++ b/mail_inline_css/README.rst @@ -0,0 +1,101 @@ +.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg + :target: http://www.gnu.org/licenses/agpl + :alt: License: AGPL-3 + +=============== +Mail Inline CSS +=============== + +When you send HTML emails you can't use style tags but instead you have +to put inline ``style`` attributes on every element. So from this: + +.. code:: html + + + +

Peter

+

Hej

+ + +You want this: + +.. code:: html + + +

Peter

+

Hej

+ + +This module use premailer library to do this. + +It parses an HTML page, looks up ``style`` blocks +and parses the CSS. It then uses the ``lxml.html`` parser to modify the +DOM tree of the page accordingly. + +Installation +============ + +To install this module, you need first to install `premailer` python library with: + +.. code:: bash + + pip install premailer + + +Usage +===== + +Just use any mail template as Odoo standard feature + +.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas + :alt: Try me on Runbot + :target: https://runbot.odoo-community.org/runbot/205/10 + + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues +`_. In case of trouble, please +check there if your issue has already been reported. If you spotted it first, +help us smash it by providing detailed and welcomed feedback. + +Credits +======= + +Images +------ + +* Odoo Community Association: `Icon `_. + +Contributors +------------ + +* David BEAL + +Do not contact contributors directly about support or help with technical issues. + +Funders +------- + +The development of this module has been financially supported by: + +* Akretion + +Maintainer +---------- + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +This module is maintained by the OCA. + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +To contribute to this module, please visit https://odoo-community.org. diff --git a/mail_inline_css/__init__.py b/mail_inline_css/__init__.py new file mode 100644 index 00000000..0650744f --- /dev/null +++ b/mail_inline_css/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/mail_inline_css/__manifest__.py b/mail_inline_css/__manifest__.py new file mode 100644 index 00000000..a0c9d942 --- /dev/null +++ b/mail_inline_css/__manifest__.py @@ -0,0 +1,18 @@ +# coding: utf-8 +# © 2017 David BEAL @ Akretion +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +{ + 'name': 'Mail Inline CSS', + "summary": "Convert style tags in inline style in your mails", + 'version': '10.0.1.0.0', + 'author': 'Akretion, Odoo Community Association (OCA)', + 'website': 'https://github.com/OCA/social', + 'license': 'AGPL-3', + 'category': 'Tools', + 'depends': ['mail'], + 'installable': True, + "external_dependencies": { + "python": ['premailer'], + }, +} diff --git a/mail_inline_css/models/__init__.py b/mail_inline_css/models/__init__.py new file mode 100644 index 00000000..37a9875b --- /dev/null +++ b/mail_inline_css/models/__init__.py @@ -0,0 +1 @@ +from . import mail diff --git a/mail_inline_css/models/mail.py b/mail_inline_css/models/mail.py new file mode 100644 index 00000000..58135b2b --- /dev/null +++ b/mail_inline_css/models/mail.py @@ -0,0 +1,24 @@ +# coding: utf-8 +# © 2017 David BEAL @ Akretion +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +import logging +from odoo import models + +_logger = logging.getLogger(__name__) + +try: + from premailer import transform +except (ImportError, IOError) as err: + _logger.debug(err) + + +class MailTemplate(models.Model): + _inherit = 'mail.template' + + def generate_email(self, res_ids, fields=None): + res = super(MailTemplate, self).generate_email(res_ids, fields=fields) + for id in res: + if res[id].get('body_html'): + res[id]['body_html'] = transform(res[id]['body_html']) + return res From dffca470c309df6d0dc0b2d2756fd2570af028fe Mon Sep 17 00:00:00 2001 From: David Beal Date: Tue, 2 Jan 2018 15:59:43 +0100 Subject: [PATCH 02/28] IMP README use case --- mail_inline_css/README.rst | 8 ++++++++ mail_inline_css/models/mail.py | 5 ++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/mail_inline_css/README.rst b/mail_inline_css/README.rst index b76d1dfe..b67fc9c2 100644 --- a/mail_inline_css/README.rst +++ b/mail_inline_css/README.rst @@ -55,6 +55,14 @@ Just use any mail template as Odoo standard feature :target: https://runbot.odoo-community.org/runbot/205/10 +Note: + + Odoo with module web_editor already implements this feature on the client side (js). + This module brings this server side feature for cases without js part. It could the more stable way over the Odoo versions with a stable api in a dedicated library + with adhoc python unit tests. + + + Bug Tracker =========== diff --git a/mail_inline_css/models/mail.py b/mail_inline_css/models/mail.py index 58135b2b..a4be0194 100644 --- a/mail_inline_css/models/mail.py +++ b/mail_inline_css/models/mail.py @@ -18,7 +18,6 @@ class MailTemplate(models.Model): def generate_email(self, res_ids, fields=None): res = super(MailTemplate, self).generate_email(res_ids, fields=fields) - for id in res: - if res[id].get('body_html'): - res[id]['body_html'] = transform(res[id]['body_html']) + if 'body_html' in res: + res['body_html'] = transform(res['body_html']) return res From a34f91044098094e94e9af28bc9eac5dd3dc05c3 Mon Sep 17 00:00:00 2001 From: OCA Transbot Date: Tue, 16 Jan 2018 15:09:00 +0100 Subject: [PATCH 03/28] OCA Transbot updated translations from Transifex --- mail_inline_css/i18n/de.po | 24 +++++++++++++++++++++++ mail_inline_css/i18n/es.po | 24 +++++++++++++++++++++++ mail_inline_css/i18n/es_MX.po | 25 ++++++++++++++++++++++++ mail_inline_css/i18n/fr.po | 24 +++++++++++++++++++++++ mail_inline_css/i18n/hr.po | 25 ++++++++++++++++++++++++ mail_inline_css/i18n/it.po | 24 +++++++++++++++++++++++ mail_inline_css/i18n/mail_inline_css.pot | 20 +++++++++++++++++++ mail_inline_css/i18n/nl_NL.po | 25 ++++++++++++++++++++++++ mail_inline_css/i18n/zh_CN.po | 25 ++++++++++++++++++++++++ 9 files changed, 216 insertions(+) create mode 100644 mail_inline_css/i18n/de.po create mode 100644 mail_inline_css/i18n/es.po create mode 100644 mail_inline_css/i18n/es_MX.po create mode 100644 mail_inline_css/i18n/fr.po create mode 100644 mail_inline_css/i18n/hr.po create mode 100644 mail_inline_css/i18n/it.po create mode 100644 mail_inline_css/i18n/mail_inline_css.pot create mode 100644 mail_inline_css/i18n/nl_NL.po create mode 100644 mail_inline_css/i18n/zh_CN.po diff --git a/mail_inline_css/i18n/de.po b/mail_inline_css/i18n/de.po new file mode 100644 index 00000000..9410bae6 --- /dev/null +++ b/mail_inline_css/i18n/de.po @@ -0,0 +1,24 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mail_inline_css +# +# Translators: +# Niki Waibel , 2018 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2018-01-16 03:47+0000\n" +"PO-Revision-Date: 2018-01-16 03:47+0000\n" +"Last-Translator: Niki Waibel , 2018\n" +"Language-Team: German (https://www.transifex.com/oca/teams/23907/de/)\n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: mail_inline_css +#: model:ir.model,name:mail_inline_css.model_mail_template +msgid "Email Templates" +msgstr "E-Mail Vorlagen" diff --git a/mail_inline_css/i18n/es.po b/mail_inline_css/i18n/es.po new file mode 100644 index 00000000..f9e8adff --- /dev/null +++ b/mail_inline_css/i18n/es.po @@ -0,0 +1,24 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mail_inline_css +# +# Translators: +# Pedro M. Baeza , 2018 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2018-01-16 03:47+0000\n" +"PO-Revision-Date: 2018-01-16 03:47+0000\n" +"Last-Translator: Pedro M. Baeza , 2018\n" +"Language-Team: Spanish (https://www.transifex.com/oca/teams/23907/es/)\n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: mail_inline_css +#: model:ir.model,name:mail_inline_css.model_mail_template +msgid "Email Templates" +msgstr "Plantillas de correo electrónico" diff --git a/mail_inline_css/i18n/es_MX.po b/mail_inline_css/i18n/es_MX.po new file mode 100644 index 00000000..6f0a1ddc --- /dev/null +++ b/mail_inline_css/i18n/es_MX.po @@ -0,0 +1,25 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mail_inline_css +# +# Translators: +# OCA Transbot , 2018 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2018-01-16 03:47+0000\n" +"PO-Revision-Date: 2018-01-16 03:47+0000\n" +"Last-Translator: OCA Transbot , 2018\n" +"Language-Team: Spanish (Mexico) (https://www.transifex.com/oca/teams/23907/" +"es_MX/)\n" +"Language: es_MX\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: mail_inline_css +#: model:ir.model,name:mail_inline_css.model_mail_template +msgid "Email Templates" +msgstr "Plantillas de Correo Electrónico" diff --git a/mail_inline_css/i18n/fr.po b/mail_inline_css/i18n/fr.po new file mode 100644 index 00000000..2c65dc44 --- /dev/null +++ b/mail_inline_css/i18n/fr.po @@ -0,0 +1,24 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mail_inline_css +# +# Translators: +# Quentin THEURET , 2018 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2018-01-16 03:47+0000\n" +"PO-Revision-Date: 2018-01-16 03:47+0000\n" +"Last-Translator: Quentin THEURET , 2018\n" +"Language-Team: French (https://www.transifex.com/oca/teams/23907/fr/)\n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +#. module: mail_inline_css +#: model:ir.model,name:mail_inline_css.model_mail_template +msgid "Email Templates" +msgstr "Modèles de courriel" diff --git a/mail_inline_css/i18n/hr.po b/mail_inline_css/i18n/hr.po new file mode 100644 index 00000000..09a454f2 --- /dev/null +++ b/mail_inline_css/i18n/hr.po @@ -0,0 +1,25 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mail_inline_css +# +# Translators: +# OCA Transbot , 2018 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2018-01-16 03:47+0000\n" +"PO-Revision-Date: 2018-01-16 03:47+0000\n" +"Last-Translator: OCA Transbot , 2018\n" +"Language-Team: Croatian (https://www.transifex.com/oca/teams/23907/hr/)\n" +"Language: hr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" + +#. module: mail_inline_css +#: model:ir.model,name:mail_inline_css.model_mail_template +msgid "Email Templates" +msgstr "Predlošci mailova" diff --git a/mail_inline_css/i18n/it.po b/mail_inline_css/i18n/it.po new file mode 100644 index 00000000..0e35e8cf --- /dev/null +++ b/mail_inline_css/i18n/it.po @@ -0,0 +1,24 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mail_inline_css +# +# Translators: +# Marius Marolla , 2018 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2018-01-16 03:47+0000\n" +"PO-Revision-Date: 2018-01-16 03:47+0000\n" +"Last-Translator: Marius Marolla , 2018\n" +"Language-Team: Italian (https://www.transifex.com/oca/teams/23907/it/)\n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: mail_inline_css +#: model:ir.model,name:mail_inline_css.model_mail_template +msgid "Email Templates" +msgstr "Modelli Email" diff --git a/mail_inline_css/i18n/mail_inline_css.pot b/mail_inline_css/i18n/mail_inline_css.pot new file mode 100644 index 00000000..c7f5e2a4 --- /dev/null +++ b/mail_inline_css/i18n/mail_inline_css.pot @@ -0,0 +1,20 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mail_inline_css +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: <>\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: mail_inline_css +#: model:ir.model,name:mail_inline_css.model_mail_template +msgid "Email Templates" +msgstr "" + diff --git a/mail_inline_css/i18n/nl_NL.po b/mail_inline_css/i18n/nl_NL.po new file mode 100644 index 00000000..c92add5c --- /dev/null +++ b/mail_inline_css/i18n/nl_NL.po @@ -0,0 +1,25 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mail_inline_css +# +# Translators: +# Peter Hageman , 2018 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2018-01-16 03:47+0000\n" +"PO-Revision-Date: 2018-01-16 03:47+0000\n" +"Last-Translator: Peter Hageman , 2018\n" +"Language-Team: Dutch (Netherlands) (https://www.transifex.com/oca/" +"teams/23907/nl_NL/)\n" +"Language: nl_NL\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: mail_inline_css +#: model:ir.model,name:mail_inline_css.model_mail_template +msgid "Email Templates" +msgstr "E-mailsjablonen" diff --git a/mail_inline_css/i18n/zh_CN.po b/mail_inline_css/i18n/zh_CN.po new file mode 100644 index 00000000..19c6cce4 --- /dev/null +++ b/mail_inline_css/i18n/zh_CN.po @@ -0,0 +1,25 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mail_inline_css +# +# Translators: +# OCA Transbot , 2018 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2018-01-16 03:47+0000\n" +"PO-Revision-Date: 2018-01-16 03:47+0000\n" +"Last-Translator: OCA Transbot , 2018\n" +"Language-Team: Chinese (China) (https://www.transifex.com/oca/teams/23907/" +"zh_CN/)\n" +"Language: zh_CN\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#. module: mail_inline_css +#: model:ir.model,name:mail_inline_css.model_mail_template +msgid "Email Templates" +msgstr "Email 模板" From 0f7d7ad81cd00dd50ac455e6d140b169dde46e94 Mon Sep 17 00:00:00 2001 From: Timon Tschanz Date: Wed, 16 Jan 2019 16:11:17 +0100 Subject: [PATCH 04/28] [11.0][MIG] mail_inline_css --- mail_inline_css/README.rst | 2 +- mail_inline_css/__manifest__.py | 5 ++--- mail_inline_css/i18n/mail_inline_css.pot | 20 -------------------- mail_inline_css/models/mail.py | 5 ++--- 4 files changed, 5 insertions(+), 27 deletions(-) delete mode 100644 mail_inline_css/i18n/mail_inline_css.pot diff --git a/mail_inline_css/README.rst b/mail_inline_css/README.rst index b67fc9c2..3b362ebe 100644 --- a/mail_inline_css/README.rst +++ b/mail_inline_css/README.rst @@ -52,7 +52,7 @@ Just use any mail template as Odoo standard feature .. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas :alt: Try me on Runbot - :target: https://runbot.odoo-community.org/runbot/205/10 + :target: https://runbot.odoo-community.org/runbot/205/11 Note: diff --git a/mail_inline_css/__manifest__.py b/mail_inline_css/__manifest__.py index a0c9d942..c4e87d31 100644 --- a/mail_inline_css/__manifest__.py +++ b/mail_inline_css/__manifest__.py @@ -1,11 +1,10 @@ -# coding: utf-8 -# © 2017 David BEAL @ Akretion +# Copyright 2017 David BEAL @ Akretion # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). { 'name': 'Mail Inline CSS', "summary": "Convert style tags in inline style in your mails", - 'version': '10.0.1.0.0', + 'version': '11.0.1.0.0', 'author': 'Akretion, Odoo Community Association (OCA)', 'website': 'https://github.com/OCA/social', 'license': 'AGPL-3', diff --git a/mail_inline_css/i18n/mail_inline_css.pot b/mail_inline_css/i18n/mail_inline_css.pot deleted file mode 100644 index c7f5e2a4..00000000 --- a/mail_inline_css/i18n/mail_inline_css.pot +++ /dev/null @@ -1,20 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * mail_inline_css -# -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server 10.0\n" -"Report-Msgid-Bugs-To: \n" -"Last-Translator: <>\n" -"Language-Team: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Plural-Forms: \n" - -#. module: mail_inline_css -#: model:ir.model,name:mail_inline_css.model_mail_template -msgid "Email Templates" -msgstr "" - diff --git a/mail_inline_css/models/mail.py b/mail_inline_css/models/mail.py index a4be0194..a941a939 100644 --- a/mail_inline_css/models/mail.py +++ b/mail_inline_css/models/mail.py @@ -1,5 +1,4 @@ -# coding: utf-8 -# © 2017 David BEAL @ Akretion +# Copyright 2017 David BEAL @ Akretion # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). import logging @@ -17,7 +16,7 @@ class MailTemplate(models.Model): _inherit = 'mail.template' def generate_email(self, res_ids, fields=None): - res = super(MailTemplate, self).generate_email(res_ids, fields=fields) + res = super().generate_email(res_ids, fields=fields) if 'body_html' in res: res['body_html'] = transform(res['body_html']) return res From c130ab79c09cde693d48e0b5df113d0807eef2c0 Mon Sep 17 00:00:00 2001 From: Timon Tschanz Date: Wed, 16 Jan 2019 17:08:14 +0100 Subject: [PATCH 05/28] [IMP] mail_inline_css: Improve and add test cov --- mail_inline_css/README.rst | 121 ++--- mail_inline_css/__manifest__.py | 15 +- mail_inline_css/demo/demo_mail_template.xml | 10 + mail_inline_css/demo/demo_template.xml | 84 ++++ mail_inline_css/models/__init__.py | 2 +- mail_inline_css/models/mail.py | 22 - mail_inline_css/models/mail_template.py | 28 ++ mail_inline_css/readme/CONTRIBUTORS.rst | 4 + mail_inline_css/readme/DESCRIPTION.rst | 4 + mail_inline_css/static/description/index.html | 425 ++++++++++++++++++ mail_inline_css/tests/__init__.py | 1 + .../tests/test_mail_inline_styles.py | 62 +++ 12 files changed, 677 insertions(+), 101 deletions(-) create mode 100644 mail_inline_css/demo/demo_mail_template.xml create mode 100644 mail_inline_css/demo/demo_template.xml delete mode 100644 mail_inline_css/models/mail.py create mode 100644 mail_inline_css/models/mail_template.py create mode 100644 mail_inline_css/readme/CONTRIBUTORS.rst create mode 100644 mail_inline_css/readme/DESCRIPTION.rst create mode 100644 mail_inline_css/static/description/index.html create mode 100644 mail_inline_css/tests/__init__.py create mode 100644 mail_inline_css/tests/test_mail_inline_styles.py diff --git a/mail_inline_css/README.rst b/mail_inline_css/README.rst index 3b362ebe..5e9b5f7a 100644 --- a/mail_inline_css/README.rst +++ b/mail_inline_css/README.rst @@ -1,109 +1,80 @@ -.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg - :target: http://www.gnu.org/licenses/agpl - :alt: License: AGPL-3 - =============== Mail Inline CSS =============== -When you send HTML emails you can't use style tags but instead you have -to put inline ``style`` attributes on every element. So from this: - -.. code:: html - - - -

Peter

-

Hej

- - -You want this: - -.. code:: html - - -

Peter

-

Hej

- - -This module use premailer library to do this. - -It parses an HTML page, looks up ``style`` blocks -and parses the CSS. It then uses the ``lxml.html`` parser to modify the -DOM tree of the page accordingly. - -Installation -============ - -To install this module, you need first to install `premailer` python library with: - -.. code:: bash - - pip install premailer - - -Usage -===== +.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -Just use any mail template as Odoo standard feature +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fsocial-lightgray.png?logo=github + :target: https://github.com/OCA/social/tree/11.0/mail_inline_css + :alt: OCA/social +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/social-11-0/social-11-0-mail_inline_css + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png + :target: https://runbot.odoo-community.org/runbot/205/11.0 + :alt: Try me on Runbot -.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas - :alt: Try me on Runbot - :target: https://runbot.odoo-community.org/runbot/205/11 +|badge1| |badge2| |badge3| |badge4| |badge5| +Convert styles to inline styles and make them play nice with emails. -Note: - - Odoo with module web_editor already implements this feature on the client side (js). - This module brings this server side feature for cases without js part. It could the more stable way over the Odoo versions with a stable api in a dedicated library - with adhoc python unit tests. +This module sole usage is to provide the same parsing functionality as in +the web editor but for the templates imported directly in database. +**Table of contents** +.. contents:: + :local: Bug Tracker =========== -Bugs are tracked on `GitHub Issues -`_. In case of trouble, please -check there if your issue has already been reported. If you spotted it first, -help us smash it by providing detailed and welcomed feedback. +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us smashing it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. Credits ======= -Images ------- +Authors +~~~~~~~ -* Odoo Community Association: `Icon `_. +* Akretion +* camptocamp Contributors ------------- +~~~~~~~~~~~~ * David BEAL +* Akim Juillerat +* Simone Orsi +* Patrick Tombez -Do not contact contributors directly about support or help with technical issues. - -Funders -------- - -The development of this module has been financially supported by: +Maintainers +~~~~~~~~~~~ -* Akretion - -Maintainer ----------- +This module is maintained by the OCA. .. image:: https://odoo-community.org/logo.png :alt: Odoo Community Association :target: https://odoo-community.org -This module is maintained by the OCA. - OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use. -To contribute to this module, please visit https://odoo-community.org. +This module is part of the `OCA/social `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/mail_inline_css/__manifest__.py b/mail_inline_css/__manifest__.py index c4e87d31..32da0bb9 100644 --- a/mail_inline_css/__manifest__.py +++ b/mail_inline_css/__manifest__.py @@ -1,17 +1,26 @@ # Copyright 2017 David BEAL @ Akretion -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +# Copyright 2019 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). { 'name': 'Mail Inline CSS', "summary": "Convert style tags in inline style in your mails", 'version': '11.0.1.0.0', - 'author': 'Akretion, Odoo Community Association (OCA)', + 'author': 'Akretion, camptocamp, Odoo Community Association (OCA)', 'website': 'https://github.com/OCA/social', 'license': 'AGPL-3', 'category': 'Tools', - 'depends': ['mail'], 'installable': True, "external_dependencies": { "python": ['premailer'], }, + "depends": [ + "email_template_qweb", + ], + "data": [ + ], + "demo": [ + "demo/demo_template.xml", + "demo/demo_mail_template.xml", + ], } diff --git a/mail_inline_css/demo/demo_mail_template.xml b/mail_inline_css/demo/demo_mail_template.xml new file mode 100644 index 00000000..2a6d5f70 --- /dev/null +++ b/mail_inline_css/demo/demo_mail_template.xml @@ -0,0 +1,10 @@ + + + + Inline styles demo + qweb + + + Demo email inline styles + + diff --git a/mail_inline_css/demo/demo_template.xml b/mail_inline_css/demo/demo_template.xml new file mode 100644 index 00000000..3b80f533 --- /dev/null +++ b/mail_inline_css/demo/demo_template.xml @@ -0,0 +1,84 @@ + + + + diff --git a/mail_inline_css/models/__init__.py b/mail_inline_css/models/__init__.py index 37a9875b..44e83956 100644 --- a/mail_inline_css/models/__init__.py +++ b/mail_inline_css/models/__init__.py @@ -1 +1 @@ -from . import mail +from . import mail_template diff --git a/mail_inline_css/models/mail.py b/mail_inline_css/models/mail.py deleted file mode 100644 index a941a939..00000000 --- a/mail_inline_css/models/mail.py +++ /dev/null @@ -1,22 +0,0 @@ -# Copyright 2017 David BEAL @ Akretion -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). - -import logging -from odoo import models - -_logger = logging.getLogger(__name__) - -try: - from premailer import transform -except (ImportError, IOError) as err: - _logger.debug(err) - - -class MailTemplate(models.Model): - _inherit = 'mail.template' - - def generate_email(self, res_ids, fields=None): - res = super().generate_email(res_ids, fields=fields) - if 'body_html' in res: - res['body_html'] = transform(res['body_html']) - return res diff --git a/mail_inline_css/models/mail_template.py b/mail_inline_css/models/mail_template.py new file mode 100644 index 00000000..9bb40311 --- /dev/null +++ b/mail_inline_css/models/mail_template.py @@ -0,0 +1,28 @@ +# Copyright 2017 David BEAL @ Akretion +# Copyright 2019 Camptocamp SA + +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import api, models + +try: + from premailer import transform +except (ImportError, IOError) as err: + import logging + _logger = logging.getLogger(__name__) + _logger.debug(err) + + +class MailTemplate(models.Model): + _inherit = 'mail.template' + + @api.multi + def generate_email(self, res_ids, fields=None): + """Use `premailer` to convert styles to inline styles.""" + result = super().generate_email(res_ids, fields=fields) + if isinstance(res_ids, int): + result['body_html'] = transform(result['body_html']) + else: + for __, data in result.items(): + data['body_html'] = transform(data['body_html']) + return result diff --git a/mail_inline_css/readme/CONTRIBUTORS.rst b/mail_inline_css/readme/CONTRIBUTORS.rst new file mode 100644 index 00000000..fcd33779 --- /dev/null +++ b/mail_inline_css/readme/CONTRIBUTORS.rst @@ -0,0 +1,4 @@ +* David BEAL +* Akim Juillerat +* Simone Orsi +* Patrick Tombez diff --git a/mail_inline_css/readme/DESCRIPTION.rst b/mail_inline_css/readme/DESCRIPTION.rst new file mode 100644 index 00000000..30957362 --- /dev/null +++ b/mail_inline_css/readme/DESCRIPTION.rst @@ -0,0 +1,4 @@ +Convert styles to inline styles and make them play nice with emails. + +This module sole usage is to provide the same parsing functionality as in +the web editor but for the templates imported directly in database. diff --git a/mail_inline_css/static/description/index.html b/mail_inline_css/static/description/index.html new file mode 100644 index 00000000..533c0879 --- /dev/null +++ b/mail_inline_css/static/description/index.html @@ -0,0 +1,425 @@ + + + + + + +Mail Inline CSS + + + +
+

Mail Inline CSS

+ + +

Beta License: AGPL-3 OCA/social Translate me on Weblate Try me on Runbot

+

Convert styles to inline styles and make them play nice with emails.

+

This module sole usage is to provide the same parsing functionality as in +the web editor but for the templates imported directly in database.

+

Table of contents

+ +
+

Bug Tracker

+

Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us smashing it by providing a detailed and welcomed +feedback.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • Akretion
  • +
  • camptocamp
  • +
+
+ +
+

Maintainers

+

This module is maintained by the OCA.

+Odoo Community Association +

OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use.

+

This module is part of the OCA/social project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+ + diff --git a/mail_inline_css/tests/__init__.py b/mail_inline_css/tests/__init__.py new file mode 100644 index 00000000..46429763 --- /dev/null +++ b/mail_inline_css/tests/__init__.py @@ -0,0 +1 @@ +from . import test_mail_inline_styles diff --git a/mail_inline_css/tests/test_mail_inline_styles.py b/mail_inline_css/tests/test_mail_inline_styles.py new file mode 100644 index 00000000..96e73bc1 --- /dev/null +++ b/mail_inline_css/tests/test_mail_inline_styles.py @@ -0,0 +1,62 @@ +# Copyright 2019 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +from lxml import html +from odoo.tests import SavepointCase + + +class TestMailInlineStyles(SavepointCase): + + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.mail_template = cls.env.ref( + 'mail_inline_css.email_template_demo') + cls.demo_user = cls.env.ref('base.user_demo') + + def to_xml_node(self, html_): + return html.fragments_fromstring(html_) + + def parse_node_style(self, node): + """ Convert node CSS string to Python dict""" + res = {} + for style in node.attrib.get('style', '').split(';'): + l = style.split(':') + res[l[0].strip()] = l[1].strip() + return res + + def find_by_id(self, node, html_id): + return node.xpath('//*[@id="{}"]'.format(html_id)) + + def assertNodeStyle(self, node, expected): + self.assertIn('style', node.attrib) + self.assertEqual(self.parse_node_style(node), expected) + + def test_generate_mail(self): + res = self.mail_template.generate_email( + [self.demo_user.id], fields=['body_html'] + ) + body_html_string = res[self.demo_user.id].get('body_html') + html_node = self.to_xml_node(body_html_string)[0] + + expected = { + 'main_logo': { + 'max-width': '300px' + }, + 'main_wrapper': { + 'max-width': '620px', + 'margin': '0 auto', + 'border': '1px solid #ccc', + 'font-size': '18px', + 'font-family': 'verdana', + 'color': '#6B6E71' + }, + 'main_footer': { + 'padding-top': '0', + 'font-size': '120%', + 'padding': '30px 40px' + } + } + + for html_id, expected_style in expected.items(): + node = self.find_by_id(html_node, html_id)[0] + self.assertNodeStyle(node, expected_style) From 5d40bd1d53ce1caf9d074054967a5bbbd6a91363 Mon Sep 17 00:00:00 2001 From: mpanarin Date: Fri, 18 Jan 2019 12:48:07 +0200 Subject: [PATCH 06/28] [IMP] mail_inline_css: allow passing options to premailer --- mail_inline_css/models/mail_template.py | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/mail_inline_css/models/mail_template.py b/mail_inline_css/models/mail_template.py index 9bb40311..647fbdf7 100644 --- a/mail_inline_css/models/mail_template.py +++ b/mail_inline_css/models/mail_template.py @@ -6,8 +6,8 @@ from odoo import api, models try: - from premailer import transform -except (ImportError, IOError) as err: + from premailer import Premailer +except (ImportError, IOError) as err: # pragma: no cover import logging _logger = logging.getLogger(__name__) _logger.debug(err) @@ -21,8 +21,19 @@ def generate_email(self, res_ids, fields=None): """Use `premailer` to convert styles to inline styles.""" result = super().generate_email(res_ids, fields=fields) if isinstance(res_ids, int): - result['body_html'] = transform(result['body_html']) + premailer = Premailer( + html=result['body_html'], + **self._get_premailer_options(), + ) + result['body_html'] = premailer.transform() else: for __, data in result.items(): - data['body_html'] = transform(data['body_html']) + premailer = Premailer( + html=data['body_html'], + **self._get_premailer_options(), + ) + data['body_html'] = premailer.transform() return result + + def _get_premailer_options(self): + return {} From 290d80b0079e6e0d4fd819dc8f4a66dff03a7ae5 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Tue, 28 May 2019 10:26:15 +0000 Subject: [PATCH 07/28] [ADD] icon.png --- mail_inline_css/i18n/de.po | 22 ++++++++++ mail_inline_css/i18n/es.po | 22 ++++++++++ mail_inline_css/i18n/es_MX.po | 22 ++++++++++ mail_inline_css/i18n/fr.po | 22 ++++++++++ mail_inline_css/i18n/hr.po | 22 ++++++++++ mail_inline_css/i18n/it.po | 22 ++++++++++ mail_inline_css/i18n/mail_inline_css.pot | 40 ++++++++++++++++++ mail_inline_css/i18n/nl_NL.po | 22 ++++++++++ mail_inline_css/i18n/zh_CN.po | 22 ++++++++++ mail_inline_css/static/description/icon.png | Bin 0 -> 9455 bytes mail_inline_css/static/description/index.html | 2 +- 11 files changed, 217 insertions(+), 1 deletion(-) create mode 100644 mail_inline_css/i18n/mail_inline_css.pot create mode 100644 mail_inline_css/static/description/icon.png diff --git a/mail_inline_css/i18n/de.po b/mail_inline_css/i18n/de.po index 9410bae6..ec9d321d 100644 --- a/mail_inline_css/i18n/de.po +++ b/mail_inline_css/i18n/de.po @@ -18,7 +18,29 @@ msgstr "" "Content-Transfer-Encoding: \n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" +#. module: mail_inline_css +#: model:mail.template,subject:mail_inline_css.email_template_demo +msgid "Demo email inline styles" +msgstr "" + #. module: mail_inline_css #: model:ir.model,name:mail_inline_css.model_mail_template msgid "Email Templates" msgstr "E-Mail Vorlagen" + +#. module: mail_inline_css +#: model:ir.ui.view,arch_db:mail_inline_css.demo_email_hello +msgid "Hello" +msgstr "" + +#. module: mail_inline_css +#: model:ir.ui.view,arch_db:mail_inline_css.demo_email_hello +msgid "" +"This e-mail styles are inline rendered although its template defines styles " +"as embedded CSS!" +msgstr "" + +#. module: mail_inline_css +#: model:ir.ui.view,arch_db:mail_inline_css.demo_email_hello +msgid "www.example.com" +msgstr "" diff --git a/mail_inline_css/i18n/es.po b/mail_inline_css/i18n/es.po index f9e8adff..f057b9b0 100644 --- a/mail_inline_css/i18n/es.po +++ b/mail_inline_css/i18n/es.po @@ -18,7 +18,29 @@ msgstr "" "Content-Transfer-Encoding: \n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" +#. module: mail_inline_css +#: model:mail.template,subject:mail_inline_css.email_template_demo +msgid "Demo email inline styles" +msgstr "" + #. module: mail_inline_css #: model:ir.model,name:mail_inline_css.model_mail_template msgid "Email Templates" msgstr "Plantillas de correo electrónico" + +#. module: mail_inline_css +#: model:ir.ui.view,arch_db:mail_inline_css.demo_email_hello +msgid "Hello" +msgstr "" + +#. module: mail_inline_css +#: model:ir.ui.view,arch_db:mail_inline_css.demo_email_hello +msgid "" +"This e-mail styles are inline rendered although its template defines styles " +"as embedded CSS!" +msgstr "" + +#. module: mail_inline_css +#: model:ir.ui.view,arch_db:mail_inline_css.demo_email_hello +msgid "www.example.com" +msgstr "" diff --git a/mail_inline_css/i18n/es_MX.po b/mail_inline_css/i18n/es_MX.po index 6f0a1ddc..d6e784f9 100644 --- a/mail_inline_css/i18n/es_MX.po +++ b/mail_inline_css/i18n/es_MX.po @@ -19,7 +19,29 @@ msgstr "" "Content-Transfer-Encoding: \n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" +#. module: mail_inline_css +#: model:mail.template,subject:mail_inline_css.email_template_demo +msgid "Demo email inline styles" +msgstr "" + #. module: mail_inline_css #: model:ir.model,name:mail_inline_css.model_mail_template msgid "Email Templates" msgstr "Plantillas de Correo Electrónico" + +#. module: mail_inline_css +#: model:ir.ui.view,arch_db:mail_inline_css.demo_email_hello +msgid "Hello" +msgstr "" + +#. module: mail_inline_css +#: model:ir.ui.view,arch_db:mail_inline_css.demo_email_hello +msgid "" +"This e-mail styles are inline rendered although its template defines styles " +"as embedded CSS!" +msgstr "" + +#. module: mail_inline_css +#: model:ir.ui.view,arch_db:mail_inline_css.demo_email_hello +msgid "www.example.com" +msgstr "" diff --git a/mail_inline_css/i18n/fr.po b/mail_inline_css/i18n/fr.po index 2c65dc44..adb110a3 100644 --- a/mail_inline_css/i18n/fr.po +++ b/mail_inline_css/i18n/fr.po @@ -18,7 +18,29 @@ msgstr "" "Content-Transfer-Encoding: \n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" +#. module: mail_inline_css +#: model:mail.template,subject:mail_inline_css.email_template_demo +msgid "Demo email inline styles" +msgstr "" + #. module: mail_inline_css #: model:ir.model,name:mail_inline_css.model_mail_template msgid "Email Templates" msgstr "Modèles de courriel" + +#. module: mail_inline_css +#: model:ir.ui.view,arch_db:mail_inline_css.demo_email_hello +msgid "Hello" +msgstr "" + +#. module: mail_inline_css +#: model:ir.ui.view,arch_db:mail_inline_css.demo_email_hello +msgid "" +"This e-mail styles are inline rendered although its template defines styles " +"as embedded CSS!" +msgstr "" + +#. module: mail_inline_css +#: model:ir.ui.view,arch_db:mail_inline_css.demo_email_hello +msgid "www.example.com" +msgstr "" diff --git a/mail_inline_css/i18n/hr.po b/mail_inline_css/i18n/hr.po index 09a454f2..4300cfb9 100644 --- a/mail_inline_css/i18n/hr.po +++ b/mail_inline_css/i18n/hr.po @@ -19,7 +19,29 @@ msgstr "" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" +#. module: mail_inline_css +#: model:mail.template,subject:mail_inline_css.email_template_demo +msgid "Demo email inline styles" +msgstr "" + #. module: mail_inline_css #: model:ir.model,name:mail_inline_css.model_mail_template msgid "Email Templates" msgstr "Predlošci mailova" + +#. module: mail_inline_css +#: model:ir.ui.view,arch_db:mail_inline_css.demo_email_hello +msgid "Hello" +msgstr "" + +#. module: mail_inline_css +#: model:ir.ui.view,arch_db:mail_inline_css.demo_email_hello +msgid "" +"This e-mail styles are inline rendered although its template defines styles " +"as embedded CSS!" +msgstr "" + +#. module: mail_inline_css +#: model:ir.ui.view,arch_db:mail_inline_css.demo_email_hello +msgid "www.example.com" +msgstr "" diff --git a/mail_inline_css/i18n/it.po b/mail_inline_css/i18n/it.po index 0e35e8cf..89c98151 100644 --- a/mail_inline_css/i18n/it.po +++ b/mail_inline_css/i18n/it.po @@ -18,7 +18,29 @@ msgstr "" "Content-Transfer-Encoding: \n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" +#. module: mail_inline_css +#: model:mail.template,subject:mail_inline_css.email_template_demo +msgid "Demo email inline styles" +msgstr "" + #. module: mail_inline_css #: model:ir.model,name:mail_inline_css.model_mail_template msgid "Email Templates" msgstr "Modelli Email" + +#. module: mail_inline_css +#: model:ir.ui.view,arch_db:mail_inline_css.demo_email_hello +msgid "Hello" +msgstr "" + +#. module: mail_inline_css +#: model:ir.ui.view,arch_db:mail_inline_css.demo_email_hello +msgid "" +"This e-mail styles are inline rendered although its template defines styles " +"as embedded CSS!" +msgstr "" + +#. module: mail_inline_css +#: model:ir.ui.view,arch_db:mail_inline_css.demo_email_hello +msgid "www.example.com" +msgstr "" diff --git a/mail_inline_css/i18n/mail_inline_css.pot b/mail_inline_css/i18n/mail_inline_css.pot new file mode 100644 index 00000000..51a029de --- /dev/null +++ b/mail_inline_css/i18n/mail_inline_css.pot @@ -0,0 +1,40 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mail_inline_css +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 11.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: <>\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: mail_inline_css +#: model:mail.template,subject:mail_inline_css.email_template_demo +msgid "Demo email inline styles" +msgstr "" + +#. module: mail_inline_css +#: model:ir.model,name:mail_inline_css.model_mail_template +msgid "Email Templates" +msgstr "" + +#. module: mail_inline_css +#: model:ir.ui.view,arch_db:mail_inline_css.demo_email_hello +msgid "Hello" +msgstr "" + +#. module: mail_inline_css +#: model:ir.ui.view,arch_db:mail_inline_css.demo_email_hello +msgid "This e-mail styles are inline rendered although its template defines styles as embedded CSS!" +msgstr "" + +#. module: mail_inline_css +#: model:ir.ui.view,arch_db:mail_inline_css.demo_email_hello +msgid "www.example.com" +msgstr "" + diff --git a/mail_inline_css/i18n/nl_NL.po b/mail_inline_css/i18n/nl_NL.po index c92add5c..d852a29e 100644 --- a/mail_inline_css/i18n/nl_NL.po +++ b/mail_inline_css/i18n/nl_NL.po @@ -19,7 +19,29 @@ msgstr "" "Content-Transfer-Encoding: \n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" +#. module: mail_inline_css +#: model:mail.template,subject:mail_inline_css.email_template_demo +msgid "Demo email inline styles" +msgstr "" + #. module: mail_inline_css #: model:ir.model,name:mail_inline_css.model_mail_template msgid "Email Templates" msgstr "E-mailsjablonen" + +#. module: mail_inline_css +#: model:ir.ui.view,arch_db:mail_inline_css.demo_email_hello +msgid "Hello" +msgstr "" + +#. module: mail_inline_css +#: model:ir.ui.view,arch_db:mail_inline_css.demo_email_hello +msgid "" +"This e-mail styles are inline rendered although its template defines styles " +"as embedded CSS!" +msgstr "" + +#. module: mail_inline_css +#: model:ir.ui.view,arch_db:mail_inline_css.demo_email_hello +msgid "www.example.com" +msgstr "" diff --git a/mail_inline_css/i18n/zh_CN.po b/mail_inline_css/i18n/zh_CN.po index 19c6cce4..3d6d2157 100644 --- a/mail_inline_css/i18n/zh_CN.po +++ b/mail_inline_css/i18n/zh_CN.po @@ -19,7 +19,29 @@ msgstr "" "Content-Transfer-Encoding: \n" "Plural-Forms: nplurals=1; plural=0;\n" +#. module: mail_inline_css +#: model:mail.template,subject:mail_inline_css.email_template_demo +msgid "Demo email inline styles" +msgstr "" + #. module: mail_inline_css #: model:ir.model,name:mail_inline_css.model_mail_template msgid "Email Templates" msgstr "Email 模板" + +#. module: mail_inline_css +#: model:ir.ui.view,arch_db:mail_inline_css.demo_email_hello +msgid "Hello" +msgstr "" + +#. module: mail_inline_css +#: model:ir.ui.view,arch_db:mail_inline_css.demo_email_hello +msgid "" +"This e-mail styles are inline rendered although its template defines styles " +"as embedded CSS!" +msgstr "" + +#. module: mail_inline_css +#: model:ir.ui.view,arch_db:mail_inline_css.demo_email_hello +msgid "www.example.com" +msgstr "" diff --git a/mail_inline_css/static/description/icon.png b/mail_inline_css/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3a0328b516c4980e8e44cdb63fd945757ddd132d GIT binary patch literal 9455 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 z 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 Xviia!U7SGha1wx#SCgwmn*{w2TRX*I literal 0 HcmV?d00001 diff --git a/mail_inline_css/static/description/index.html b/mail_inline_css/static/description/index.html index 533c0879..2096ddae 100644 --- a/mail_inline_css/static/description/index.html +++ b/mail_inline_css/static/description/index.html @@ -3,7 +3,7 @@ - + Mail Inline CSS +
+
+ + + + + + + +
+ + + +
+
+
+
+

Hello .

+
+
+

This e-mail styles are inline rendered although its template defines styles as embedded CSS!

+
+
+ +
+ + + diff --git a/mail_inline_css/demo/demo_template.xml b/mail_inline_css/demo/demo_template.xml deleted file mode 100644 index 6171b77c..00000000 --- a/mail_inline_css/demo/demo_template.xml +++ /dev/null @@ -1,92 +0,0 @@ - - - - diff --git a/mail_inline_css/models/mail_template.py b/mail_inline_css/models/mail_template.py index 96fa7862..ff1f9210 100644 --- a/mail_inline_css/models/mail_template.py +++ b/mail_inline_css/models/mail_template.py @@ -3,22 +3,16 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -from odoo import models - -try: - from premailer import Premailer -except (OSError, ImportError) as err: # pragma: no cover - import logging +from premailer import Premailer - _logger = logging.getLogger(__name__) - _logger.debug(err) +from odoo import models class MailTemplate(models.Model): _inherit = "mail.template" - def _render_template_postprocess(self, rendered): - rendered = super()._render_template_postprocess(rendered) + def _render_template_postprocess(self, model, rendered): + rendered = super()._render_template_postprocess(model, rendered) for res_id, html in rendered.items(): rendered[res_id] = self._premailer_apply_transform(html) return rendered diff --git a/mail_inline_css/readme/CONTRIBUTORS.md b/mail_inline_css/readme/CONTRIBUTORS.md index 04e458cf..3a131d66 100644 --- a/mail_inline_css/readme/CONTRIBUTORS.md +++ b/mail_inline_css/readme/CONTRIBUTORS.md @@ -11,3 +11,4 @@ - [Trobz](https://trobz.com): > - Son Ho \<\> + > - Khoi Vo \<\> diff --git a/mail_inline_css/readme/CREDITS.md b/mail_inline_css/readme/CREDITS.md index 291e14c8..d514b5fb 100644 --- a/mail_inline_css/readme/CREDITS.md +++ b/mail_inline_css/readme/CREDITS.md @@ -1,2 +1,2 @@ -The migration of this module from 15.0 to 16.0 was financially supported +The migration of this module from 16.0 to 18.0 was financially supported by Camptocamp diff --git a/mail_inline_css/static/description/index.html b/mail_inline_css/static/description/index.html index 09745d66..326db3c1 100644 --- a/mail_inline_css/static/description/index.html +++ b/mail_inline_css/static/description/index.html @@ -369,7 +369,7 @@

Mail Inline CSS

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! source digest: sha256:e3cd02099a2beb9db6980920f3d0547a5154e4a386f2f3e3bf189342a85a2110 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --> -

Beta License: AGPL-3 OCA/social Translate me on Weblate Try me on Runboat

+

Beta License: AGPL-3 OCA/mail Translate me on Weblate Try me on Runboat

Convert styles to inline styles and make them play nice with emails.

This module sole usage is to provide the same parsing functionality as in the web editor but for the templates imported directly in database.

@@ -388,10 +388,10 @@

Mail Inline CSS

Bug Tracker

-

Bugs are tracked on GitHub Issues. +

Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed -feedback.

+feedback.

Do not contact contributors directly about support or help with technical issues.

@@ -420,6 +420,7 @@

Contributors

@@ -427,7 +428,7 @@

Contributors

Other credits

-

The migration of this module from 15.0 to 16.0 was financially supported +

The migration of this module from 16.0 to 18.0 was financially supported by Camptocamp

@@ -439,7 +440,7 @@

Maintainers

OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use.

-

This module is part of the OCA/social project on GitHub.

+

This module is part of the OCA/mail project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

diff --git a/mail_inline_css/tests/test_mail_inline_styles.py b/mail_inline_css/tests/test_mail_inline_styles.py index 09e1598e..2b5a2183 100644 --- a/mail_inline_css/tests/test_mail_inline_styles.py +++ b/mail_inline_css/tests/test_mail_inline_styles.py @@ -31,8 +31,8 @@ def assertNodeStyle(self, node, expected): self.assertEqual(self.parse_node_style(node), expected) def test_generate_mail(self): - res = self.mail_template.generate_email( - [self.demo_user.id], fields=["body_html"] + res = self.mail_template._generate_template( + [self.demo_user.id], render_fields=["body_html"] ) body_html_string = res[self.demo_user.id].get("body_html") html_node = self.to_xml_node(body_html_string)[0] diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 00000000..4fb8946e --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +# generated from manifests external_dependencies +premailer