【发布时间】:2011-03-27 01:04:25
【问题描述】:
我没有找到 jinja2 和 Mako 的一个很好的比较。你会用什么来完成什么任务?
我个人对 mako(在 pylons 网络应用程序环境中)感到满意,但我很想知道 jinja2 是否有一些 mako 没有的不错的功能/改进? - 或者可能是缺点?-
【问题讨论】:
标签: python templates template-engine mako jinja2
我没有找到 jinja2 和 Mako 的一个很好的比较。你会用什么来完成什么任务?
我个人对 mako(在 pylons 网络应用程序环境中)感到满意,但我很想知道 jinja2 是否有一些 mako 没有的不错的功能/改进? - 或者可能是缺点?-
【问题讨论】:
标签: python templates template-engine mako jinja2
我个人更喜欢 Jinja2 的语法而不是 Mako 的语法。以Mako website中的这个例子为例
<%inherit file="base.html"/>
<%
rows = [[v for v in range(0,10)] for row in range(0,10)]
%>
<table>
% for row in rows:
${makerow(row)}
% endfor
</table>
<%def name="makerow(row)">
<tr>
% for name in row:
<td>${name}</td>\
% endfor
</tr>
</%def>
这里有太多的构造,我什至必须先查阅文档才能开始。哪些标签以<% 开头并以/> 结尾?其中哪些可以使用%> 关闭?为什么我想输出一个变量(${foo})时,还有另一种输入模板语言的方法?这个 faux XML 中的某些指令像标签一样关闭并具有属性,这是怎么回事?
这是 Jinja2 中的等效示例:
{% extends "base.html" %}
<table>
{% for row in rows %}
{{ makerow(row) }}
{% endfor %}
</table>
{% macro make_row(row) %}
<tr>
{% for name in row %}
<td>{{ name }}</td>
{% endfor %}
</tr>
{% endmacro %}
Jinja2 有过滤器,我听说 Mako 也有,但我没见过。过滤器函数的行为不像常规函数,它们采用被过滤值的隐式第一个参数。因此,在 Mako 中,您可能会这样写:
${escape(default(get_name(user), "No Name"))}
这太可怕了。在 Jinja2 中你会写:
{{ user | get_name | default('No Name') | escape }}
在我看来,Jinja2 示例的可读性非常好。 Jinja2 更常规,标签以可预测的方式开始和结束,{% %} 用于处理和控制指令,{{ }} 用于输出变量。
但这些都是个人喜好。我不知道选择 Jinja2 而不是 Mako 的更重要的理由,反之亦然。 Pylons 非常棒,您可以使用任何一种!
更新包含 Jinja2 宏。尽管无论如何都是人为的,但我认为 Jinja2 示例更易于阅读和理解。 Mako 的指导理念是“Python 是一种很棒的脚本语言。不要重新发明轮子……您的模板可以处理它!”但是 Jinja2 的宏(实际上是整个语言)看起来更像是 Mako 所做的 Python!
【讨论】:
<% /> 与 <% %> 并没有那么令人困惑(块与内联代码)。 Mako 也有过滤功能,它们看起来都一样。
len 和enumerate,除非您将它们作为上下文变量传递。而使用.__len__ 或loop.index0 是丑陋且不直观的。
${user | get_name, default('No Name') , escape}。很明显,您从未使用过 Mako,这非常好,但您几乎无法进行合理的比较,或者称我们的语法“愚蠢”,谢谢!
看看wheezy.template例子:
@require(user, items)
Welcome, @user.name!
@if items:
@for i in items:
@i.name: @i.price!s.
@end
@else:
No items found.
@end
【讨论】:
%define(make_row, <tr> %for(name in row, <td>%name%</td> ) </tr> ) %set(body, <table> %for(row in rows, %makerow% ) </table> ) %expand(%include(base.html))