一个简单但灵活的模板系统,用于动态生成文本输出。
项目描述
Twiddler旨在提供从模板源渲染文本内容的方法。它有两个主要目标
能够使用设计者提供的源材料,并且完全不改变它们,或者在需要添加任何标记的情况下与视觉编辑器无缝协作。
尽可能简单,同时仍然能够处理所有需要完成的事情。这特别意味着使用Twiddler不需要了解任何新语言!
开始之前
您需要了解您希望生成的内容的语法,无论是XML、HTML还是纯文本。
您需要了解一些Python。您只需要了解很少的知识就可以开始,但如果您想进行更高级的操作,您需要了解更多。
安装
安装Twiddler最简单的方法是
easy_install twiddler
或者,如果您正在使用zc.buildout,只需指定“twiddler”作为必需的egg。
但是,您也可以通过解压源代码分发并放置“twiddler”文件夹在您的PYTHONPATH上的任何位置来安装。
如果您不使用easy_install或zc.buildout安装,您还需要确保以下Python包在您的PYTHONPATH上可用
elementtree
尽管从Python 2.5及以上版本开始,这是标准配置,但Twiddler尚未与Python 2.5附带的版本兼容。无论您使用Python的哪个版本,都必须单独安装ElementTree,并且可以从以下地址下载:
zope.interface
这是Zope 2.9.0及以上版本的标准配置,但如果您不使用Zope,则需要从以下地址下载:
http://download.zope.org/distribution/
尽管.tar.gz文件中的INSTALL.TXT提供了说明,但您需要了解Python eggs。
zope.testing
只有在您想运行包含的单元和文档测试时才需要此模块。它是Zope 2.9.0及以上版本的标准配置,但如果您不使用Zope并想运行测试,则可以单独从以下地址下载:
http://download.zope.org/distribution/
尽管.tar.gz文件中的INSTALL.TXT提供了说明,但您需要了解Python eggs。
有关使用各种Python Web框架安装的说明,请参阅下方的“更多信息”部分。
用法
为了解释Twiddler的工作原理,我们将使用纯Python版本的Twiddler,并从头开始进行所有操作。一旦您为纯Python安装了Twiddler,以下示例都将正常工作。
因此,首先,您需要从一些源字符串创建一个Twiddler
>>> from twiddler import Twiddler >>> t = Twiddler('''<html> ... <body> ... <div id="greeting">Hello world!</div> ... <div name="stuff">I'm in <i>Italic</i>!</div> ... <form><input name="test" value="value"/></form> ... </body> ... </html>''')
从那时起,您可以通过找到元素并替换其部分、删除它或重复它来使内容动态化。这可以按需多次执行。在任何时候,您都可以调用Twiddler的render方法来获取一个可以返回给浏览器的字符串。
下面是几个简单的替换示例
>>> t['greeting'].replace('Hello user!',style='color: red;') >>> t['test'].replace(value='my value')
我们可以通过渲染Twiddler来查看结果
>>> print t.render() <html> <body> <div id="greeting" style="color: red;">Hello user!</div> <div name="stuff">I'm in <i>Italic</i>!</div> <form><input name="test" value="my value" /></form> </body> </html>
下面是一个简单的删除示例
>>> t['stuff'].remove() >>> print t.render() <html> <body> <div id="greeting" style="color: red;">Hello user!</div> <form><input name="test" value="my value" /></form> </body> </html>
下面是一个简单的重复示例
>>> e = t['greeting'].repeater() >>> for i in range(3): ... e.repeat('Hello user %i!'%i,id='greeting'+str(i)) <twiddler.TwiddlerElement instance at ...> <twiddler.TwiddlerElement instance at ...> <twiddler.TwiddlerElement instance at ...>>>> print t.render() <html> <body> <div id="greeting0" style="color: red;">Hello user 0!</div> <div id="greeting1" style="color: red;">Hello user 1!</div> <div id="greeting2" style="color: red;">Hello user 2!</div> <form><input name="test" value="my value" /></form> </body> </html>
您可能想知道输出中出现的<twiddler.twiddler…>行是从哪里来的。好吧,这是Python shell行为的一个副作用,但这是另一个功能造成的。
repeat方法返回刚刚插入的元素。如果您想重复更复杂的结构,这很有用。
>>> t = Twiddler('''<html> ... <body> ... <div name="row">This is row <i name="number">1</i></div> ... </body> ... </html>''') >>> e = t['row'].repeater() >>> for i in range(3): ... c = e.repeat() ... c['number'].replace(str(i),name=False) >>> print t.render() <html> <body> <div name="row">This is row <i>0</i></div> <div name="row">This is row <i>1</i></div> <div name="row">This is row <i>2</i></div> </body> </html>
现在,您可能已经注意到,到目前为止,我们都是从代码外部对元素进行操作的。有些人发现源代码和操纵源代码的代码之间的双重性,尤其是当它们可能位于磁盘上的不同文件中时,感到不愉快。为了使这些人过得更愉快,Twiddler支持在源代码本身中包含代码块,如下所示:
>>> from twiddler.input.default import DefaultWithCodeBlock >>> t = Twiddler('''<html> ... <!--twiddler ... def myfunc(t): ... e = t['row'].repeater() ... for i in range(3): ... c = e.repeat() ... c['number'].replace(str(i),name=False) ... --> ... <body> ... <div name="row">This is row <i name="number">1</i></div> ... </body> ... </html>''',input=DefaultWithCodeBlock)
当调用render方法时执行此代码
>>> print t.render() <html> <body> <div name="row">This is row <i>0</i></div> <div name="row">This is row <i>1</i></div> <div name="row">This is row <i>2</i></div> </body> </html>
您会注意到,为了使它工作,必须指定不同的输入解析器。这是因为代码块执行在Twiddler的源来自用户输入时可能构成一个重大的安全问题,所以Twiddler默认使用的解析器不会寻找要执行的代码。
现在,当生成HTML时,您通常希望许多页面具有相同的样式。Twiddler允许您通过允许您将一个Twiddler的部分插入到另一个Twiddler中来做到这一点。
例如,这是我们的站点模板:
>>> template = Twiddler('''<html> ... <body> ... <h1>The Site Header</h1> ... <div id="content">Content goes here</div> ... </body> ... </html>''')
这是特定的页面
>>> page = Twiddler(''' ... <html> ... <body> ... <div id="content">This is our page content!</div> ... </body> ... </html> ... ''')
现在,要将它们组合起来,我们执行以下操作:
>>> t = template.clone() >>> t['content'].replace(page['content']) >>> print t.render() <html> <body> <h1>The Site Header</h1> <div id="content">This is our page content!</div> </body> </html>
最后,Twiddler可以在任何时刻进行序列化。
>>> from cPickle import dumps,loads >>> s = dumps(t)
这允许它们以部分渲染的状态保存到磁盘上。这应该会提供一些很好的机会来加速页面渲染,因为您只需要在需要时渲染需要更改的内容。
例如,我们刚刚序列化的Twiddler可以被重新加载,只需替换内容,而无需从单独的页面和模板组件重新构建页面。
>>> from_cache = loads(s) >>> from_cache['content'].replace('Our new content!') >>> print from_cache.render() <html> <body> <h1>The Site Header</h1> <div id="content">Our new content!</div> </body> </html>
更多信息
有关Twiddler各个方面更详细的信息,可以在发行版的“docs”目录中找到。
- replace.txt
涵盖了replace方法的全部可能用途
- repeat.txt
涵盖了repeat方法的全部可能用途
- search.txt
涵盖了所有可以搜索元素的方法
- filters.txt
涵盖了使用过滤器进行特定调用以替换和重复的功能,以及设置默认过滤器,如HTML引号和国际化的设置。
- inandout.txt
涵盖了Twiddler与不同输入解析器和输出渲染器的使用。这也更详细地涵盖了默认的解析和渲染对象。
- execution.txt
涵盖了在调用渲染或执行方法后可以执行代码的所有方式。
- templating.txt
涵盖了使用render、execute和clone方法从多个Twiddler构建完整输出。
此外,Twiddler组成部分实现的接口在“twiddler”包中的interfaces.py文件中描述。
有关使用Twiddler与各种Python Web框架的说明和示例,也可以在以下文件中找到,包含在其子包中
- zope2/readme.txt
涵盖了在纯Zope 2中使用Twiddler的方法。
许可
版权(c)2006-2008 Simplistix Ltd
本软件以MIT许可证发布:[https://open-source.org.cn/licenses/mit-license.html](https://open-source.org.cn/licenses/mit-license.html) 请参阅license.txt以获取更多详细信息。
鸣谢
- Chris Withers
想法和开发
- Fredrik Lundh
出色的ElementTree库
- Django团队
关于过滤器的想法
- Guido van Rossum
因为他对XML的固执,使我更深入地思考了解析和渲染;-)
变更
0.9.1
将readme.txt更改为reStructuredText
修复原型基准文件中的语法错误。
0.9.0
对distutils、setuptools和zc.buildout进行了修改
0.8.0
初始发布
项目详情
下载文件
下载适合您平台的文件。如果您不确定选择哪个,请了解更多关于安装包的信息。
源分布
构建分布
twiddler-0.9.1.tar.gz的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | ae3ceb967339598b6e98b8a0026230663c0ecb8a70aeda1c8010f9006ec44db3 |
|
MD5 | 98c920945e6afa34b71523381bf647fa |
|
BLAKE2b-256 | 3880f9fc71734f072d1716ab0e551d17f80b5bbc0d9de07035bf9968fa574f42 |
twiddler-0.9.1-py2.5.egg的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 67ab3e8c826b86f0e3171a9e9f9a1d708558666056a3915bedb13de273290377 |
|
MD5 | a373cafc51db2457a96dffea35f57d20 |
|
BLAKE2b-256 | bca2b7d182efc20aebd376581293e64cea01ca863f2e94694e0490b9f0d9fd63 |