跳转到主要内容

Pythonic HTML生成/模板(无模板文件)

项目描述

使用html5tagger进行HTML5生成:快速、纯Python、无依赖

如果您正在寻找一种更高效、更简洁的生成HTML5的方法,那么html5tagger将是您的最佳选择!此模块提供了一个简化的HTML5语法,您可以使用Python仅使用Python创建整个文档模板。告别手动编写HTML标签的笨拙和易错的过程。

使用html5tagger,您可以安全快速地生成HTML5,无需任何依赖,这对于重视速度和简洁的开发者来说是完美的解决方案。并且由于其纯Python实现,您永远不必担心兼容性问题或向您的项目添加额外的库。

准备好简化您的页面渲染过程了吗?开始非常快。相信我们,一旦您尝试了html5tagger,您将不再回到Jinja2或手动HTML编写!

pip install html5tagger

简介

html5tagger为HTML生成提供两个起点:使用E作为创建HTML片段的空构建器,或使用Document生成带有DOCTYPE声明的完整HTML文档。两者都生成一个Builder对象,以防您需要它进行类型注解。

创建一个片段,并通过点表示法添加标签

E.p("Powered by:").br.a(href="...")("html5tagger")
<p>Powered by:<br><a href="...">html5tagger</a>

包含模板变量和其他功能的完整示例

from html5tagger import Document, E

# Create a document
doc = Document(
    E.TitleText_,           # The first argument is for <title>, adding variable TitleText
    lang="en",              # Keyword arguments for <html> attributes

    # Just list the resources you need, no need to remember link/script tags
    _urls=[ "style.css", "favicon.png", "manifest.json" ]
)

# Upper case names are template variables. You can modify them later.
doc.Head_
doc.h1.TitleText_("Demo")   # Goes inside <h1> and updates <title> as well

# This has been a hard problem for DOM other such generators:
doc.p("A paragraph with ").a("a link", href="/files")(" and ").em("formatting")

# Use with for complex nesting (not often needed)
with doc.table(id="data"):
    doc.tr.th("First").th("Second").th("Third")
    doc.TableRows_

# Let's add something to the template variables
doc.Head._script("console.log('</script> escaping is weird')")

table = doc.TableRows
for row in range(10):
    table.tr
    for col in range(3):
        table.td(row * col)

# Or remove the table data we just added
doc.TableRows = None

您可以使用str(doc)获取HTML代码,并且通常使用doc直接也会有预期效果(例如,提供HTML响应)。Jupyter Notebooks将其渲染为HTML。对于调试,请使用repr(doc),其中可见模板变量

>>> doc
《Document Builder》
<!DOCTYPE html><html lang=en><meta charset="utf-8">
<title>《TitleText:Demo》</title>
<link href="style.css" rel=stylesheet>
<link href="favicon.png" rel=icon type="image/png">
<link href="manifest.json" rel=manifest>
《Head:<script>console.log('<\/script> escaping is weird')</script><h1>《TitleText:Demo》</h1>
<p>A paragraph with <a href="/files">a link</a> and <em>formatting</em>
<table id=data>
  <tr><th>First<th>Second<th>Third
  《TableRows》
</table>

实际HTML输出类似。文档中不会添加空格,除非内容包含换行符。您可能会注意到body和其他熟悉标签缺失,并且转义非常少。这是HTML5:文档符合标准,冗余更少。

模板

使用模板变量构建文档一次,仅在渲染时更新动态部分,以提高性能。通过doc.TitleText访问模板变量,并在标签名后添加括号内的内容。标签名末尾的下划线表示该标签已添加到文档中,并且可以在括号内包含内容,但同一行的任何其他标签都将添加到原始文档中,而不是模板。

嵌套

HTML5元素,如<p>,不需要任何关闭标签,因此我们可以继续添加内容,而不必担心何时应该关闭。此模块不使用任何可选或禁止的元素的关闭标签。

当您向标签添加内容或添加另一个标签时,标签会自动关闭。仅设置属性不会关闭元素。如果后续内容不应放入其中,请使用(None)关闭空元素,例如doc.script(None, src="...")

对于像<table><ul>这样的元素,您可以使用with块、传递子片段参数或添加模板变量。与添加另一个标签不同,添加模板不会关闭其前面的标签,而是变量将放入任何打开的元素中。

with doc.ul:  # Nest using with
    doc.li("Write HTML in Python")
    doc.li("Simple syntax").ul(id="inner").InnerList_  # Nest using template
    doc.li("No need for brackets or closing tags")
    doc.ul(E.li("Easy").li("Peasy"))  # Nest using (...)

转义

所有内容和属性都会自动转义。例如,我们可以将整个文档放入iframe的srcdoc属性中,只应用必要的最小转义。使用自定义方法_script_style_comment来遵循相应的内联格式,以遵循它们自定义的转义规则。

doc = Document("Escaping & Context")
doc._style('h1::after {content: "</Style>"}').h1("<Escape>")
doc._comment("All-->OK")
doc.iframe(srcdoc=Document().p("&amp; is used for &"))
<!DOCTYPE html><meta charset="utf-8"><title>Escaping &amp; Context</title>
<style>h1::after {content: "<\/Style>"}</style><h1>&lt;Escape></h1>
<!--All‒‒>OK-->
<iframe srcdoc="<!DOCTYPE html><p>&amp;amp;amp; is used for &amp;amp;"></iframe>

在浏览器中运行良好。

名称修改和布尔属性

名称末尾的下划线将被忽略,因此尽管是Python中的保留字,但可以继续使用class_for_等其他属性。其他下划线将转换为连字符。

⚠️ 上述内容仅适用于HTML元素和属性,但模板占位符仅使用结尾的下划线来表示它将被放置在文档上,而不是用于获取使用。

布尔值将转换为短属性。

E.input(type="checkbox", id="somebox", checked=True).label(for_="somebox", aria_role="img")("🥳")
<input type=checkbox id=somebox checked><label for=somebox aria-role=img>🥳</label>

预格式化HTML

所有内容都会自动转义,除非它提供了一个返回HTML格式字符串的__html__方法。同样,此模块的构建器对象公开了__html___repr_html_访问器,允许它们在Jupyter Notebooks和各种遵循此约定的其他系统中作为HTML进行渲染。

任何预格式化HTML都可以用html5tagger.HTML(string_of_html)包装,以避免在包含在文档中时被转义,因为HTML类具有那些访问器。

⚠️ 请勿使用 HTML() 对文本进行操作,尤其是用户发送的消息,因为这些消息可能包含您无意中作为HTML执行的内容。

性能

%timeit str(Document("benchmarking", lang="en", _urls=("foo.js", "bar.js")))
14 µs ± 153 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)

Jinja2从内存模板渲染类似文档大约需要10 µs,但它不需要格式化任何HTML。当使用html5tagger进行模板化时,渲染时间降低到大约4 µs。

在上面的基准测试中,html5tagger逐个元素和属性从头开始创建整个文档。除非您需要动态创建非常大的文档,否则这应该足够快。

进一步开发

自2018年此模块投入生产使用以来,标记API没有发生变化,因此接口被认为是稳定的。

2023年添加了对模板化的支持,允许对文档的所有静态部分(作为长字符串)进行预格式化,只在模板之间填充。这是一项正在进行中的工作,尚未进行优化。

此外,2023年还添加了_script_style特殊方法。这些方法最终可能会取代非下划线自动版本,但为了现在,使用单独的方法更容易实现。

欢迎提交拉取请求。

项目详情


下载文件

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

源分发

html5tagger-1.3.0.tar.gz (14.2 kB 查看哈希值)

上传时间

构建分发

html5tagger-1.3.0-py3-none-any.whl (11.0 kB 查看哈希值)

上传时间 Python 3

由以下机构支持