Dominate
Dominate 是一个用于使用优雅的 DOM API 创建和操作 HTML 文档的 Python 库。
它允许你用纯 Python 非常简洁地编写 HTML 页面,从而无需学习另一种模板语言,并让你能够利用 Python 更强大的功能。
Python:
import dominate
from dominate.tags import *
doc = dominate.document(title='Dominate your HTML')
with doc.head:
link(rel='stylesheet', href='style.css')
script(type='text/javascript', src='script.js')
with doc:
with div(id='header').add(ol()):
for i in ['home', 'about', 'contact']:
li(a(i.title(), href='/%s.html' % i))
with div():
attr(cls='body')
p('Lorem ipsum..')
print(doc)
请提供需要翻译的 Markdown 文档内容。
<!DOCTYPE html>
<html>
<head>
<title>Dominate your HTML</title>
<link href="style.css" rel="stylesheet">
<script src="script.js" type="text/javascript"></script>
</head>
<body>
<div id="header">
<ol>
<li>
<a href="/home.html">Home</a>
</li>
<li>
<a href="/about.html">About</a>
</li>
<li>
<a href="/contact.html">Contact</a>
</li>
</ol>
</div>
<div class="body">
<p>Lorem ipsum..</p>
</div>
</body>
</html>
安装
安装 dominate 的推荐方式是使用
pip:
pip install dominate
开发者
- Tom Flanagan - tom@zkpq.ca
- Jake Wharton - jakewharton@gmail.com
- Brad Janke
Git 仓库位于 github.com/Knio/dominate
示例
所有示例均假设您已导入相应的标签或整个标签集:
from dominate.tags import *
Hello, World!
dominate 最基本的功能为每个 HTML 元素暴露一个类,其构造函数
接受子元素、文本或关键字属性。dominate 节点通过 __str__、__unicode__ 和 render() 方法返回其 HTML 表示。
print(html(body(h1('Hello, World!'))))
<html>
<body>
<h1>Hello, World!</h1>
</body>
</html>
Attributes
Dominate 还可以使用关键字参数将属性附加到你的标签上。大多数属性直接取自 HTML 规范,并带有一些变体。
对于与 Python 的 保留关键字 冲突的属性 class 和 for,你可以使用以下别名:
| class | for |
|---|---|
| _class | _for |
| cls | fr |
| className | htmlFor |
| class_name | html_for |
test = label(cls='classname anothername', fr='someinput')
print(test)
<label class="classname anothername" for="someinput"></label>
使用 data_* 用于 自定义 HTML5 data 属性。
test = div(data_employee='101011')
print(test)
<div data-employee="101011"></div>
你还可以通过类似字典的接口修改标签的属性:
header = div()
header['id'] = 'header'
print(header)
<div id="header"></div>
复杂结构
通过使用 += 运算符和 .add() 方法,您可以轻松创建更高级的结构。
创建一个简单的列表:
list = ul()
for item in range(4):
list += li('Item #', item)
print(list)
<ul>
<li>Item #0</li>
<li>Item #1</li>
<li>Item #2</li>
<li>Item #3</li>
</ul>
dominate 支持可迭代对象,以帮助您简化代码:
print(ul(li(a(name, href=link), __pretty=False) for name, link in menu_items))
<ul>
<li><a href="/home/">Home</a></li>
<li><a href="/about/">About</a></li>
<li><a href="/downloads/">Downloads</a></li>
<li><a href="/links/">Links</a></li>
</ul>
一个简单的文档树:
_html = html()
_body = _html.add(body())
header = _body.add(div(id='header'))
content = _body.add(div(id='content'))
footer = _body.add(div(id='footer'))
print(_html)
<html>
<body>
<div id="header"></div>
<div id="content"></div>
<div id="footer"></div>
</body>
</html>
为了编写整洁的代码,.add() 方法以元组形式返回子元素。上述示例可以清理并扩展如下:
_html = html()
_head, _body = _html.add(head(title('Simple Document Tree')), body())
names = ['header', 'content', 'footer']
header, content, footer = _body.add([div(id=name) for name in names])
print(_html)
<html>
<head>
<title>Simple Document Tree</title>
</head>
<body>
<div id="header"></div>
<div id="content"></div>
<div id="footer"></div>
</body>
</html>
您可以通过类似字典的接口修改标签的属性:
header = div()
header['id'] = 'header'
print(header)
<div id="header"></div>
或者通过数组行接口获取标签的子元素:
header = div('Test')
header[0] = 'Hello World'
print(header)
<div>Hello World</div>
也可以使用对象来创建注释!
print(comment('BEGIN HEADER'))
<!--BEGIN HEADER-->
print(comment(p('Upgrade to newer IE!'), condition='lt IE9'))
<!--[if lt IE9]>
<p>Upgrade to newer IE!</p>
<![endif]-->
渲染
默认情况下,render() 会尝试使所有输出对人类可读,每行一个 HTML
元素,并带有两个空格的缩进。
此行为可通过创建元素时的 __pretty(默认:除 pre 等特定元素类型外为 True)属性,以及
render() 的 pretty(默认:True)、indent(默认: )和 xhtml(默认:False)
参数进行控制。渲染选项会传播到所有后代节点。
a = div(span('Hello World'))
print(a.render())
<div>
<span>Hello World</span>
</div>
print(a.render(pretty=False))
<div><span>Hello World</span></div>
print(a.render(indent='\t'))
<div>
<span>Hello World</span>
</div>
a = div(span('Hello World'), __pretty=False)
print(a.render())
<div><span>Hello World</span></div>
d = div()
with d:
hr()
p("Test")
br()
print(d.render())
print(d.render(xhtml=True))
<div>
<hr>
<p>Test</p><br>
</div>
<div>
<hr />
<p>Test</p><br />
</div>
上下文管理器
你也可以使用 Python 的 with 语句添加子元素:
h = ul()
with h:
li('One')
li('Two')
li('Three')
print(h)
<ul>
<li>One</li>
<li>Two</li>
<li>Three</li>
</ul>
您可以将此与其他添加子元素的机制一起使用,包括嵌套 with 语句,并且它按预期工作:
h = html()
with h.add(body()).add(div(id='content')):
h1('Hello World!')
p('Lorem ipsum ...')
with table().add(tbody()):
l = tr()
l += td('One')
l.add(td('Two'))
with l:
td('Three')
print(h)
<html>
<body>
<div id="content">
<h1>Hello World!</h1>
<p>Lorem ipsum ...</p>
<table>
<tbody>
<tr>
<td>One</td>
<td>Two</td>
<td>Three</td>
</tr>
</tbody>
</table>
</div>
</body>
</html>
当上下文关闭时,任何尚未添加到其他位置的节点都会被添加到当前上下文中。
可以使用 attr 函数将属性添加到当前上下文:
d = div()
with d:
attr(id='header')
print(d)
<div id="header"></div>
并且可以使用 dominate.util.text 函数添加文本节点:
from dominate.util import text
para = p(__pretty=False)
with para:
text('Have a look at our ')
a('other products', href='/products')
print(para)
<p>Have a look at our <a href="/products">other products</a></p>
装饰器
Dominate 非常适合用于创建页面各部分的可复用组件。考虑以下示例:
def greeting(name):
with div() as d:
p('Hello, %s' % name)
return d
print(greeting('Bob'))
<div>
<p>Hello, Bob</p>
</div>
你可以看到以下模式在此处被重复:
def widget(parameters):
with tag() as t:
...
return t
通过使用标签(对象和实例)作为装饰器,可以避免这种样板代码
@div
def greeting(name):
p('Hello %s' % name)
print(greeting('Bob'))
<div>
<p>Hello Bob</p>
</div>
被装饰的函数将返回用于装饰它的那个标签的新实例,并在 with 上下文中执行,该上下文将收集在其中创建的所有节点。
如果需要向小部件的根节点添加属性或其他数据,也可以使用标签的实例作为装饰器。 每次调用被装饰的函数都会返回用于装饰它的那个节点的副本。
@div(h2('Welcome'), cls='greeting')
def greeting(name):
p('Hello %s' % name)
print(greeting('Bob'))
<div class="greeting">
<h2>Welcome</h2>
<p>Hello Bob</p>
</div>
创建文档
由于每次创建 HTML 文档的通用结构都会极其繁琐,dominate 提供了一个类来为您创建和管理它们:document。
当您创建新文档时,基本的 HTML 标签结构会为您自动创建。
d = document()
print(d)
<!DOCTYPE html>
<html>
<head>
<title>Dominate</title>
</head>
<body></body>
</html>
document 类接受 title、doctype 和 request 关键字参数。
这些参数的默认值分别为 Dominate、<!DOCTYPE html> 和 None。
document 类还提供辅助方法,允许您直接访问 title、head 和 body 节点。
d = document()
>>> d.head
<dominate.tags.head: 0 attributes, 1 children>
>>> d.body
<dominate.tags.body: 0 attributes, 0 children>
>>> d.title
u'Dominate'
document 类还提供辅助方法,允许您直接向 body 标签添加节点。
d = document()
d += h1('Hello, World!')
d += p('This is a paragraph.')
print(d)
<!DOCTYPE html>
<html>
<head>
<title>Dominate</title>
</head>
<body>
<h1>Hello, World!</h1>
<p>This is a paragraph.</p>
</body>
</html>
嵌入 HTML
如果你需要嵌入来自 markdown 等库的预格式化 HTML 节点,你可以使用 dominate.util 包中的 raw 方法来避免转义 HTML:
from dominate.util import raw
...
td(raw('<a href="example.html">Example</a>'))
如果没有原始调用,这段代码将渲染转义的 HTML,例如 lt 等。前一段代码的行为与 JavaScript 中的 td_element.innerHTML="<a href="example.html">Example</a>" 相同。
SVG
dominate.svg 模块包含类似于 dominate.tags 包含 HTML 标签的 SVG 标签。SVG 元素会自动将 _ 转换为 - 以用于虚线元素。例如:
from dominate.svg import *
print(circle(stroke_width=5))
<circle stroke-width="5"></circle>