translated

This commit is contained in:
geekpi 2020-05-26 08:41:57 +08:00
parent f41febeddd
commit c65fb8680e
2 changed files with 179 additions and 180 deletions

View File

@ -1,180 +0,0 @@
[#]: collector: (lujun9972)
[#]: translator: (geekpi)
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: subject: (3 Python templating languages you should (probably) never use)
[#]: via: (https://opensource.com/article/20/4/python-templating-languages)
[#]: author: (Moshe Zadka https://opensource.com/users/moshez)
3 Python templating languages you should (probably) never use
======
Python has accumulated a lot of templating languages, including these
three that are perfect for April Fools' Day.
![Hands on a keyboard with a Python book ][1]
When reaching for a templating language for writing a [Python][2] web application, there are an abundance of robust solutions. 
There are [Jinja2][3], [Genshi, and Mako][4]. There are even solutions like [Chameleon][5], which are a bit older, but still recommended by the [Pyramid][6] framework.
Python has been around for a long time. In that time, deep in the corners of its system, it has accumulated some almost forgotten templating languages that are well worth poking at.
Like cute koalas on top of a eucalyptus tree, happy in their ecological niche, and sometimes as dangerous to work with, these are the templating languages few have heard of—and even fewer should use.
### 3\. string.Template
Have you ever wondered, "How can I get a templating language with no features, but also without needing to **pip install** anything?" The Python standard library has you covered. While it does no looping or conditionals, the **string.Template** class is a minimal templating language.
Using it is simplicity itself.
```
>>> import string
>>> greeting = string.Template("Hello, $name, good $time!")
>>> greeting.substitute(name="OpenSource.com", time="afternoon")
'Hello, OpenSource.com, good afternoon!'
```
### 2\. twisted.web.template
What gift do you give the library that has everything?
Not a templating language, certainly, because it already has one. Nestled in **twisted.web.template** are two templating languages. One is XML-based and has a [great tutorial][7].
But there is another one, one that is based on using Python as a domain-specific language to produce HTML documents.
It is based on two primitives: **twisted.web.template.tags**, which contains tag objects, and **twisted.web.template.flattenString**, which will render them. Because it is part of Twisted, it has built-in support for rendering async results efficiently.
This example will render a silly little page:
```
async def render(reactor):
    my_title = "A Fun page"
    things = ["one", "two", "red", "blue"]
    template = tags.html(
            tags.head(
                tags.title(my_title),
            ),
            tags.body(
                tags.h1(my_title),
                tags.ul(
                    [tags.li(thing) for thing in things],
                ),
                tags.p(
                    task.deferLater(reactor, 3, lambda: "Hello "),
                    task.deferLater(reactor, 3, lambda: "world!"),
                )
            )
    )
    res = await flattenString(None, template)
    res = res.decode('utf-8')
    with open("hello.html", 'w') as fpout:
        fpout.write(res)
```
The template is regular Python code that uses the **tags.<TAGNAME>** to indicate the hierarchy. It natively supports strings as renderables, so any string is fine.
To render it, the only things you need to do are to add a preamble:
```
from twisted.internet import task, defer
from twisted.web.template import tags, flattenString
def main(reactor):
    return defer.ensureDeferred(render(reactor))
```
and an epilogue to run the whole thing:
```
`task.react(main)`
```
In just _three_ seconds (and not _six_), it will render a nice HTML page. In real-life, those **deferLater**s can be, for example, calls to an HTTP API: they will be sent and processed in parallel, without having to put in any effort. I recommend you instead read about a [far better use for Twisted][8]. But still, this works.
### 1\. Quixote
You will say, "But Python is not _optimized_ for being an HTML-spouting domain-specific language." What if, instead of settling for Python-as-is, there was a language that [transpiles][9] to Python, but is better at defining templates? A "Python template language" (PTL), if you will.
Writing your own language is sometimes said to be a dreamer's project for someone who tilts at windmills. Irony was not lost on the creators of Quixote (available on [PyPI][10]) when they decided to do exactly that.
The following will render an equivalent template to the one done with Twisted above. _Warning: the following is not valid Python_:
```
import time
def render [html] ():
    my_title = "A Fun page"
    things = ["one", "two", "red", "blue"]
    "<html><head><title>"
    my_title
    "</head></title><body><h1>"
    my_title
    "</h1>"
    "<ul>"
    for thing in things:
        "<li>"
        thing
        "</li>"
    "<p>"
    time.sleep(3)
    (lambda: "Hello ")()
    time.sleep(3)
    (lambda: "world!")()
    "</p>"
    "</body></html>"
def write():
    result = render()
    with open("hello.html", 'w') as fpout:
        fpout.write(str(result))
```
However, if you put it in a file called **template.ptl**, you can make it importable to Quixote and write out the rendered version of the template:
```
>>> from quixote import enable_ptl
>>> enable_ptl()
>>> import template
>>> template.write()
```
Quixote installs an import hook that will cause PTL files to transpile into Python. Note that this render takes _six_ seconds, not _three_; you no longer gain free asynchronicity.
### So many templates in Python
Python has a long and winding history of libraries, some of which can achieve the same outcomes in more or less similar ways (for example, Python [package management][11]).
On this April Fools' Day, I hope you enjoyed exploring three ways you _can_ create templates in Python. Instead, I recommend starting with [one of these libraries][4] for ways you _should_ template.
Do you have another esoteric way to template? Share it in the comments below!
--------------------------------------------------------------------------------
via: https://opensource.com/article/20/4/python-templating-languages
作者:[Moshe Zadka][a]
选题:[lujun9972][b]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/moshez
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/python-programming-code-keyboard.png?itok=fxiSpmnd (Hands on a keyboard with a Python book )
[2]: https://opensource.com/resources/python
[3]: https://opensource.com/article/20/2/jinja2-cheat-sheet
[4]: https://opensource.com/resources/python/template-libraries
[5]: https://chameleon.readthedocs.io/en/latest/
[6]: https://opensource.com/article/18/5/pyramid-framework
[7]: https://twistedmatrix.com/documents/13.1.0/web/howto/twisted-templates.html
[8]: https://opensource.com/article/20/3/treq-python
[9]: https://en.wikipedia.org/wiki/Source-to-source_compiler
[10]: https://pypi.org/project/Quixote/
[11]: https://opensource.com/article/19/4/managing-python-packages

View File

@ -0,0 +1,179 @@
[#]: collector: (lujun9972)
[#]: translator: (geekpi)
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: subject: (3 Python templating languages you should (probably) never use)
[#]: via: (https://opensource.com/article/20/4/python-templating-languages)
[#]: author: (Moshe Zadka https://opensource.com/users/moshez)
你应该(或许)没使用过的 3 种 Python 模板语言
======
Python 积累了许多模板语言,包括这 3 个适合在愚人节介绍的模板语言
![Hands on a keyboard with a Python book ][1]
当使用一种模板语言来编写 [Python][2] Web 应用时,它有很多健壮的解决方案。
有 [Jinja2][3]、[Genshi 和 Mako][4]。甚至还有 [Chameleon][5] 之类的解决方案,虽然有些陈旧,但仍被 [Pyramid][6] 框架推荐。
Python 已经存在了很长时间。此时,在系统的深处,它积累了一些几乎被遗忘的模板语言,它们都是值得一试的。
就像桉树顶上的可爱考拉一样,在它们的生态位中不错,有时用它们工作会危险,这些都是很少有人听说过的模板语言,使用过的应该更少。
### 3\. string.Template
你是否曾经想过:“如何获得一种没有任何特性但同时也不需要 **pip install** 的模板语言?” Python 标准库已经涵盖。虽然没有循环和条件,但 **string.Template** 类是一种最小的模板语言。
使用它很简单。
```
>>> import string
>>> greeting = string.Template("Hello, $name, good $time!")
>>> greeting.substitute(name="OpenSource.com", time="afternoon")
'Hello, OpenSource.com, good afternoon!'
```
### 2\. twisted.web.template
你会给一个有所有东西的库什么礼物?
当然,它不是一种模板语言,因为已经有一种。 嵌套在 twisted.web.template 中的是两种模板语言。 一种是基于 XML 的,并有一个[很棒的文档][7]。
但是还有另一种,一种基于使用 Python 作为领域特定语言来生成 HTML 文档。
它基于两个原语:包含标签对象的 **twisted.web.template.tags** 和渲染它们的 **twisted.web.template.flattenString**。由于它是 Twisted 的一部分,因此它内置支持高效异步渲染。
此例将渲染一个小页面:
```
async def render(reactor):
    my_title = "A Fun page"
    things = ["one", "two", "red", "blue"]
    template = tags.html(
            tags.head(
                tags.title(my_title),
            ),
            tags.body(
                tags.h1(my_title),
                tags.ul(
                    [tags.li(thing) for thing in things],
                ),
                tags.p(
                    task.deferLater(reactor, 3, lambda: "Hello "),
                    task.deferLater(reactor, 3, lambda: "world!"),
                )
            )
    )
    res = await flattenString(None, template)
    res = res.decode('utf-8')
    with open("hello.html", 'w') as fpout:
        fpout.write(res)
```
该模板是使用 **tags.<TAGNAME>** 来指示层次结构的常规 Python 代码。原生支持渲染字符串,因此任何字符串都正常。
要渲染它,你需要做的是添加调用:
```
from twisted.internet import task, defer
from twisted.web.template import tags, flattenString
def main(reactor):
    return defer.ensureDeferred(render(reactor))
```
最后写上:
```
`task.react(main)`
```
只需 _3_ 秒(而不是 _6_ 秒),它将渲染一个不错的 HTML 页面。在实际中,这些 **deferLater** 可以是对 HTTP API 的调用:它们将并行发送和处理,而无需花费精力。我建议你阅读关于[更好地使用 Twisted][8]。但是,这仍可以工作。
### 1\. Quixote
你会说:“但是 Python 并不是针对 HTML 输入而优化的领域特定语言。” 如果有一种语言可以[转化][9]到 Python但是更适合定义模板而不是像 Python 那样按原样解决呢? 如果可以的话请使用“Python 模板语言”PTL
对于攻击假想敌的人来说,写自己的语言有时被认为是梦想家的项目。当 Quixote (可用于 [PyPI][10])的创造者决定这样做时,并没有受此影响。
以下将渲染与上面 Twisted 相同的模板。 _警告以下是无效的 Python_
```
import time
def render [html] ():
    my_title = "A Fun page"
    things = ["one", "two", "red", "blue"]
    "<html><head><title>"
    my_title
    "</head></title><body><h1>"
    my_title
    "</h1>"
    "<ul>"
    for thing in things:
        "<li>"
        thing
        "</li>"
    "<p>"
    time.sleep(3)
    (lambda: "Hello ")()
    time.sleep(3)
    (lambda: "world!")()
    "</p>"
    "</body></html>"
def write():
    result = render()
    with open("hello.html", 'w') as fpout:
        fpout.write(str(result))
```
但是,如果将它放到 **template.ptl** 文件中,那么可以将其导入到 Quixote 并写出可以渲染模板的版本:
```
>>> from quixote import enable_ptl
>>> enable_ptl()
>>> import template
>>> template.write()
```
Quixote 安装一个导入钩子,它会将 PTL 文件转换为 Python。请注意此渲染需要 _6_ 秒,而不是 _3_ 秒。你不再能自由异步。
### Python 中的模板太多
Python 的库历史悠久且曲折其中一些库可以或多或少以类似的方式实现相同的结果例如Python [包管理][11])。
在这个愚人节我希望你喜欢探索这三种_可以_用 Python 创建模板的方式。另外,我建议从[这三个库之一][4]开始了解。
你是否有另一种深奥的模板方法?请在下面的评论中分享!
--------------------------------------------------------------------------------
via: https://opensource.com/article/20/4/python-templating-languages
作者:[Moshe Zadka][a]
选题:[lujun9972][b]
译者:[geekpi](https://github.com/geekpi)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/moshez
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/python-programming-code-keyboard.png?itok=fxiSpmnd (Hands on a keyboard with a Python book )
[2]: https://opensource.com/resources/python
[3]: https://opensource.com/article/20/2/jinja2-cheat-sheet
[4]: https://opensource.com/resources/python/template-libraries
[5]: https://chameleon.readthedocs.io/en/latest/
[6]: https://opensource.com/article/18/5/pyramid-framework
[7]: https://twistedmatrix.com/documents/13.1.0/web/howto/twisted-templates.html
[8]: https://opensource.com/article/20/3/treq-python
[9]: https://en.wikipedia.org/wiki/Source-to-source_compiler
[10]: https://pypi.org/project/Quixote/
[11]: https://opensource.com/article/19/4/managing-python-packages