跳转到主要内容

将CSS块转换为样式属性

项目描述

https://travis-ci.org/peterbe/premailer.svg?branch=master https://badge.fury.io/py/premailer.svg https://img.shields.io/badge/code%20style-black-000000.svg

寻找赞助商

本项目正在积极寻找企业赞助。如果您想帮助将其成为一个活跃的项目,请考虑 联系Peter,我们可以讨论放置公司标志和链接。

Python版本

我们的 tox.ini 确保premailer在

  • Python 3.4

  • Python 3.5

  • Python 3.6

  • Python 3.7

  • Python 3.8

  • PyPy

将CSS块转换为样式属性

当您发送HTML电子邮件时,您不能使用样式标签,而必须在每个元素上放置内联 style 属性。因此,从这一点

<html>
<style type="text/css">
h1 { border:1px solid black }
p { color:red;}
</style>
<h1 style="font-weight:bolder">Peter</h1>
<p>Hej</p>
</html>

您想要这个

<html>
<h1 style="font-weight:bolder; border:1px solid black">Peter</h1>
<p style="color:red">Hej</p>
</html>

premailer就是这样做的。它解析HTML页面,查找 style 块并解析CSS。然后它使用 lxml.html 解析器相应地修改页面的DOM树。

警告!默认情况下,Premailer将尝试通过URL从互联网下载任何外部样式表。如果您想阻止这种行为,可以使用allow_network=False选项。

入门指南

如果您还没有这样做,请首先安装premailer

$ pip install premailer

接下来,最基本的用法是使用快捷函数,例如:

>>> from premailer import transform
>>> print(transform("""
...         <html>
...         <style type="text/css">
...         h1 { border:1px solid black }
...         p { color:red;}
...         p::first-letter { float:left; }
...         </style>
...         <style type="text/css" data-premailer="ignore">
...         h1 { color:blue; }
...         </style>
...         <h1 style="font-weight:bolder">Peter</h1>
...         <p>Hej</p>
...         </html>
... """))
<html>
<head>
    <style type="text/css">p::first-letter {float:left}</style>
    <style type="text/css">
    h1 { color:blue; }
    </style>
</head>
<body>
    <h1 style="border:1px solid black; font-weight:bolder">Peter</h1>
    <p style="color:red">Hej</p>
</body>
</html>

transform快捷函数将使用所有选项的默认值来转换给定的HTML。

base_url=None, # Optional URL prepended to all relative links (both stylesheets and internal)
disable_link_rewrites=False, # Allow link rewrites (e.g. using base_url)
preserve_internal_links=False, # Do not preserve links to named anchors when using base_url
preserve_inline_attachments=True, # Preserve links with cid: scheme when base_url is specified
preserve_handlebar_syntax=False # Preserve handlebar syntax from being encoded
exclude_pseudoclasses=True, # Ignore pseudoclasses when processing styles
keep_style_tags=False, # Discard original style tag
include_star_selectors=False, # Ignore star selectors when processing styles
remove_classes=False, # Leave class attributes on HTML elements
capitalize_float_margin=False, # Do not capitalize float and margin properties
strip_important=True, # Remove !important from property values
external_styles=None, # Optional list of URLs to load and parse
css_text=None, # Optional CSS text to parse
method="html", # Parse input as HTML (as opposed to "xml")
base_path=None, # Optional base path to stylesheet in your file system
disable_basic_attributes=None, # Optional list of attribute names to preserve on HTML elements
disable_validation=False, # Validate CSS when parsing it with cssutils
cache_css_parsing=True, # Do cache parsed output for CSS
cssutils_logging_handler=None, # See "Capturing logging from cssutils" below
cssutils_logging_level=None,
disable_leftover_css=False, # Output CSS that was not inlined into the HEAD
align_floating_images=True, # Add align attribute for floated images
remove_unset_properties=True # Remove CSS properties if their value is unset when merged
allow_network=True # allow network access to fetch linked css files
allow_insecure_ssl=False # Don't allow unverified SSL certificates for external links
allow_loading_external_files=False # Allow loading any non-HTTP external file URL
session=None # Session used for http requests - supply your own for caching or to provide authentication

对于更高级的选项,请查看Premailer类的代码及其构造函数中的所有选项。

您还可以通过使用其主模块从命令行使用Premailer。

$ python -m premailer -h
usage: python -m premailer [options]

optional arguments:
-h, --help            show this help message and exit
-f [INFILE], --file [INFILE]
                      Specifies the input file. The default is stdin.
-o [OUTFILE], --output [OUTFILE]
                      Specifies the output file. The default is stdout.
--base-url BASE_URL
--remove-internal-links PRESERVE_INTERNAL_LINKS
                      Remove links that start with a '#' like anchors.
--exclude-pseudoclasses
                      Pseudo classes like p:last-child', p:first-child, etc
--preserve-style-tags
                      Do not delete <style></style> tags from the html
                      document.
--remove-star-selectors
                      All wildcard selectors like '* {color: black}' will be
                      removed.
--remove-classes      Remove all class attributes from all elements
--strip-important     Remove '!important' for all css declarations.
--method METHOD       The type of html to output. 'html' for HTML, 'xml' for
                      XHTML.
--base-path BASE_PATH
                      The base path for all external stylsheets.
--external-style EXTERNAL_STYLES
                      The path to an external stylesheet to be loaded.
--disable-basic-attributes DISABLE_BASIC_ATTRIBUTES
                      Disable provided basic attributes (comma separated)
--disable-validation  Disable CSSParser validation of attributes and values
--pretty              Pretty-print the outputted HTML.
--allow-insecure-ssl  Skip SSL certificate verification for external URLs.
--allow-loading-external-files Allow opening any non-HTTP external file URL.

基本示例

$ python -m premailer --base-url=http://google.com/ -f newsletter.html
<html>
<head><style>.heading { color:red; }</style></head>
<body><h1 class="heading" style="color:red"><a href="http://google.com/">Title</a></h1></body>
</html>

命令行界面支持标准输入。

$ echo '<style>.heading { color:red; }</style><h1 class="heading"><a href="/">Title</a></h1>' | python -m premailer --base-url=http://google.com/
<html>
<head><style>.heading { color:red; }</style></head>
<body><h1 class="heading" style="color:red"><a href="http://google.com/">Title</a></h1></body>
</html>

将相对URL转换为绝对URL

Premailer还可以为您做的另一件事是将相对URL(例如,“/some/page.html”)转换为绝对URL(如“http://www.peterbe.com/some/page.html”)。它将对所有没有://部分的hrefsrc属性执行此操作。例如,将以下内容:

<html>
<body>
<a href="/">Home</a>
<a href="page.html">Page</a>
<a href="http://crosstips.org">External</a>
<img src="/folder/">Folder</a>
</body>
</html>

转换为以下内容:

<html>
<body>
<a href="http://www.peterbe.com/">Home</a>
<a href="http://www.peterbe.com/page.html">Page</a>
<a href="http://crosstips.org">External</a>
<img src="http://www.peterbe.com/folder/">Folder</a>
</body>
</html>

通过使用transform('...', base_url='http://www.peterbe.com/')实现。

额外创建的HTML属性

如果CSS中包含任何易于转换为HTML属性的CSS属性,某些HTML属性也会在HTML中创建。例如,如果您有这个CSS:td { background-color:#eee; },那么它将转换为style="background-color:#eee",并作为一个HTML属性bgcolor="#eee"

这些额外属性基本上是作为一个“备份”,用于那些连样式属性都无法处理的垃圾邮件客户端。许多专业HTML新闻通讯,如亚马逊,都使用这种方式。您可以在disable_basic_attributes中禁用一些属性。

cssutils捕获日志

cssutils是Premailer用来解析CSS的库。它将使用Python的logging模块来记录它解析您的CSS时遇到的所有问题。如果您想捕获这些日志,您必须传递cssutils_logging_handlercssutils_logging_level(可选)。例如,像这样:

>>> import logging
>>> import premailer
>>> from io import StringIO
>>> mylog = StringIO()
>>> myhandler = logging.StreamHandler(mylog)
>>> p = premailer.Premailer(
...     cssutils_logging_handler=myhandler,
...     cssutils_logging_level=logging.INFO
... )
>>> result = p.transform("""
...         <html>
...         <style type="text/css">
...         @keyframes foo { from { opacity: 0; } to { opacity: 1; } }
...         </style>
...         <p>Hej</p>
...         </html>
... """)
>>> mylog.getvalue()
'CSSStylesheet: Unknown @rule found. [2:1: @keyframes]\n'

如果执行速度对您很重要

如果执行速度很重要,您很可能不仅仅是转换1个HTML文档,而是转换大量的HTML文档。那么,您应该做的第一件事就是避免使用premailer.transform函数,因为它每次都会创建一个Premailer类实例。

# WRONG WAY!
from premailer import transform

for html_string in get_html_documents():
    transformed = transform(html_string, base_url=MY_BASE_URL)
    # do something with 'transformed'

相反...

# RIGHT WAY
from premailer import Premailer

instance = Premailer(base_url=MY_BASE_URL)
for html_string in get_html_documents():
    transformed = instance.transform(html_string)
    # do something with 'transformed'

当您重复使用相同的导入Python代码并重复使用它时,还要注意的一个问题是内部memoize函数缓存可能会积累。用于控制的环境变量是PREMAILER_CACHE_MAXSIZE。如果您的作业非常大,甚至内存成为问题,这个参数可能需要一些微调。

高级选项

以下是可能对大多数常规负载用户不太重要的某些高级配置选项。

选择缓存实现

默认情况下,premailer 使用 LFUCache 缓存选择器、样式和解析后的CSS字符串。如果LFU不能满足您的需求,可以使用以下环境变量切换到其他实现。

  • PREMAILER_CACHE:可以是LRU、LFU或TTL。默认为LFU。

  • PREMAILER_CACHE_MAXSIZE:缓存中存储的最大项数。默认为128。

  • PREMAILER_CACHE_TTL:缓存条目的存活时间。仅适用于TTL缓存。默认为1小时。

开始编码

首先克隆代码并创建您需要的虚拟环境,然后运行

pip install -e ".[dev]"

然后要运行测试,运行

tox

这将为您系统上可以找到的每个Python版本运行整个测试套件。要更增量地运行测试,打开 tox.ini 并查看其工作方式。

代码风格全部为黑色

所有代码都必须使用 Black 格式化,检查此内容的最佳工具是 therapist,因为它可以帮助您运行所有操作、修复问题,并在您提交git之前确保linting通过。此项目还使用 flake8 检查Black无法检查的其他事项。

要使用 tox 进行linting检查,使用

tox -e lint

要安装 therapist 预提交钩子,只需运行

therapist install

当您运行 therapist run 时,它将仅检查您已修改的文件。要为所有文件运行,使用

therapist run --use-tracked-files

要修复所有/任何问题,运行

therapist run --use-tracked-files --fix

项目详情


发布历史 发布通知 | RSS 源

下载文件

下载您平台上的文件。如果您不确定选择哪个,请了解更多关于 安装包 的信息。

源分发

premailer-3.10.0.tar.gz (24.3 kB 查看哈希值)

上传时间 源代码

构建分发版本

premailer-3.10.0-py2.py3-none-any.whl (19.5 kB 查看哈希值)

上传时间 Python 2 Python 3

支持者