Web developers have to deal with template engines. I've been working with a lot of Python's template engines, so I think it's time to summarize them.
I. First list them according to my level of familiarity:
pyTenjin: I use it when developing Doodle and 91 Tutor.
: I use it in the development of Knowledge Daily.
PyJade: I came across it when I was developing Knowledge Daily.
Mako: I've only used it in a small project that died early on.
Jinja2: I've only done a few demos with it.
Other things aside, Django's templates, for example, are said to be slow and difficult to use, and I haven't touched them at all.
Secondly, let's talk about performance
A lot of tests are just big loops and stuff, which is pretty non-technical. In fact, the rendering time of a template is mostly consumed by string processing, including splicing, encoding, escaping, etc., while loops measure the performance of the Python runtime.
So I'd better test it with a real example, and ended up choosing Doodle's front page. It has a few sub-templates, a few loops, a few function calls and a lot of variables, so it's representative. Considering that template engines other than pyTenjin don't support localized caching, I removed the sidebars that are used for caching and only rendered the main part.
The results for 1000 renderings are: pyTenjin took 0.65 seconds, 0.9 seconds with preprocessing removed; 1.0 seconds; and Jinja2 took 1.1 seconds.
The test code is a few hundred lines and 19 files, so I'm not going to list them. Other template engines are also too lazy to test.
The advantages of @pyTenjin are obvious, especially its support for preprocessing. The main purpose of this preprocessing is to compile some constants first, so that they don't need to be processed when rendering (since they're already strings); in addition, some features can be statically decided to be turned on or off, and preprocessing can remove the code of those unneeded features (mainly if branching) in advance. It is also possible to cache the rendering results of any code segment for a period of time without having to re-render it.
@Jinja2 Slower than slow is something I didn't expect and doesn't seem to match many tests.
@Mako is expected to be similar to Jinja2. It also caches the rendering results of snippets.
@PyJade needs to convert Jade templates to other templates and has no cache, so expect it to be much slower.
Considering that there certainly isn't a performance gap of several times the size of PyJade, just pick the one that works.
III. Finally, ease of use
The advantage of @pyTenjin is that you can write arbitrary Python code.
The downside is that the markup is more complex and unique, with <?py ... ? >, <?PY ... ? >, #{...} , #{{...}} , {==... ==}, {#==... ==#}, ${...} , ${{...}} }, {#=... =#} and {#==... ==#}, but it's kinda cute.
Due to the use of the < and > symbols, when used inside HTML tags, it prevents the editor from parsing the syntax.
In addition, its tagattr() method treats the expr parameter as True when it is 0, which needs to be fixed by changing the source code, and it has no open source project to submit a pull request.
And it has only one developer, hasn't been updated in over a year, and is significantly less active.
The good thing about @ is that it works pretty well with Tornado (it comes with it, after all), and has decent functionality and performance.
The downside is that it's hard to pinpoint what was written wrong when something goes wrong, and it does have less functionality compared to other template engines (though I haven't encountered a lack of it yet).
Also, {% raw ... None is shown as None on output instead of the empty string, which makes it very tiresome to write.
It outputs HTML code with header and footer spaces removed, but individual lines of Python code appear as blank lines, which looks odd.
The advantage of @Jinja2 is that it has a lot of functionality, it defines a lot of helper functions, it has filters, and it has syntactic sugar like inline if expressions, which makes it more comfortable to write. In addition, it is able to adjust the whitespace, which makes its output HTML more beautiful.
The downside is that it's more expensive to learn, the syntax isn't pure Python anymore, and you can't even import Python modules and use list parsing expressions like [item for item in list if item].
Another serious drawback is that non-ASCII strings cannot be output, in which case the unicode type must be used, which is tricky to ensure.
The advantage of @Mako is that like pyTenjin you can write arbitrary Python code, and like Jinja2 it supports filters (actually, if you're used to function calls).
The disadvantages are also higher learning costs, more complex syntax, and unfriendliness to HTML editors.
The advantage of @PyJade is that it's the fastest to write (especially for the front-end) and there's nothing redundant.
The drawbacks are the same as with Jinja2, but worse, there is almost no documentation, and the latest release version is not available, so you need to use the development version.
For now, I think I'll stick with pyTenjin, the others either don't work well or are more expensive to learn, and the extra features don't feel like they have to be there.