我不知道这是聪明还是愚蠢。我喜欢CL-WHO而且我也喜欢Python,所以我一直在努力将两者混为一谈。我想要的是这样说:
tag("html",
lst(
tag("head"),
tag("body",
lst(
tag("h1", "This is the headline"),
tag("p", "This is the article"),
tag("p",
tag("a", "Click here for more", ["href", "http://nowhere.com"]))))))
并对此进行评估:
<html>
<head>
</head>
<body>
<h1>This is the headline</h1>
<p>This is the article</p>
<p>
<a href="http://nowhere.com">Click here for more</a>
</p>
</body>
</html>
看起来就像CL-WHO,但带有函数符号而不是s表达式。所以我开始使用这个标记生成函数:
def tag(name, inner="", attribs=[], close=True):
ret = []
ret.append('<' + name)
while attribs.__len__() > 0:
ret.append(' %s="%s"' % (attribs.pop(0),attribs.pop(0)))
ret.append(">")
if type(inner).__name__ == 'list':
ret.extend(inner)
else:
ret.append(inner)
if close:
ret.append('</%s>' % name)
return "".join(ret)
inner可以是一个列表,列表的方括号在所有Lispy代码中都是丑陋的,所以我想要一个从其参数中生成列表的函数:
def lst(*args):
return [x for x in args]
为了方便条件代码生成,你需要一个if语句,它是一个计算结果为两个结果之一的函数,就像在Lisp中一样,所以你可以嵌套它。如果不这样做,那就是必要的流量控制风格。
def fif(cond, a, b):
if cond:
return a
else:
return b
Vioila。现在您可以生成如下示例页面:
def gen(x):
"""Sample function demonstratine conditional HTML generation. Looks just like CL-WHO!"""
return tag("html",
lst(
tag("head"),
tag("body",
lst(
fif(x == 1, tag("h1", "This is the headline"), tag("h1", "No, THIS is the headline")),
tag("p", "This is the article"),
tag("p",
tag("a", "Click here for more", ["href", "http://nowhere.com"]))))))
print gen(1)
这开始分解的地方是循环。任何循环都必须被提取到一个单独的函数中。你觉得怎么样?有趣还是愚蠢?尝试一下&amp;告诉我你的想法。
答案 0 :(得分:1)
你应该html-escape每个文本节点,属性值等,或html注入和XSS会咬你。
除了全功能的模板系统(mako,genhi,变色龙,jinja等)之外,与你所做的更相似的库可能是lxml
>>> from lxml.html.builder import HTML, HEAD, BODY, H1, P, A
>>> from lxml.html import tostring
>>>
>>> h = HTML(
... HEAD(
... BODY(
... H1('This is the headline'),
... P('This is the article'),
... P(
... A('Click here for more', href='http://nowhere.com')))))
>>> print tostring(h, pretty_print=True)
<html><head><body>
<h1>This is the headline</h1>
<p>This is the article</p>
<p><a href="http://nowhere.com">Click here for more</a></p>
</body></head></html>
您可以使用三元运算符
H1("This is the headline" if x==1 else "No, THIS is the headline")