2010-06-02 152 views
4

如果有人能够帮我开始编写python模板引擎,可能有可能吗?我是python的新手,并且学习了我设法在自己的轻量级WSGI服务器上编写一个MVC框架的语言。Python模板引擎

我已经成功地编写查找和替换密钥值的脚本: (显然,这是我的脚本不如何组织或实施这只是一个例子)

from string import Template 

html = '<html>\n' 
html += ' <head>\n' 
html += ' <title>This is so Cool : In Controller HTML</title>\n' 
html += ' </head>\n' 
html += ' <body>\n' 
html += ' Home | <a href="/hi">Hi ${name}</a>\n' 
html += ' </body>\n' 
html += '<html>' 

Template(html).safe_substitute(dict(name = 'Arturo')) 

我的下一个目标是实现自定义语句,修饰符,函数等(如for'循环),但我不知道是否应该使用另一个我不知道的模块。我想到正则表达式,但我觉得这样做不会是一个有效的方式做到这一点

任何帮助表示赞赏,我相信这也会对其他人有用。

谢谢

+0

看看Django:http://code.djangoproject.com/。具体来说,看看这些:http://code.djangoproject.com/svn/django/trunk/django/template/。 – Adam 2010-06-02 07:16:26

+0

我不希望这听起来粗鲁或任何东西,但为什么编写自己的框架时,有大量的已写入的可用? Django是目前最流行的一个;我建议检查一下,看看它是如何工作的。 – 2010-06-02 07:43:37

+0

@Adam 您发布的链接(第二个链接)非常棒,看到主题中的巨头如何做,总是很好的。时间让我做一些研究 – jturo 2010-06-02 09:34:46

回答

18

Python有很多功能强大的模板语言。我更喜欢Jinja2。也请看看MakoGenshi

Mako在三个中是最快的,但它的意识形态允许在模板中有一个复杂的代码逻辑,这种模式会不时引发MVC违反原则。

genshi有很好的概念,特别是强大的功能是反转模板的继承。但三者之间速度最慢,并且实践表明,其实际功能常常在实际项目中过度消耗。

Jinja2在我个人的意见中是一个金色的中间。由于它使用类似于Django模板和模板语言的语法,因此它很容易扩展,速度很快并且很多人都很熟悉。

+0

+1为Jinja2! – fabrizioM 2010-06-02 07:49:12

+0

谢谢nailxx。 mako网站显示:Mako:1.10ms Myghty:4.52ms Cheetah:\t 1.10ms Genshi:11.46ms Django:2.74ms Kid:14.54 ms这很酷,他们花时间比较引擎。我的大脑保留信息的能力非常有限,所以我使用约定来帮助我解决这个问题。只要它不是业务逻辑(我不知道这是你的意思所说的“复杂的代码逻辑”),我可以在模板中使用代码逻辑 – jturo 2010-06-02 10:28:08

1

那么,当我决定像你一样玩耍时,TDD总是一条好路。

那么,为什么不放弃它呢?

例如,创建一个名为jturo_template.py写:

import re 
import unittest 

class JTuroTemplate(object): 
    u"""JTuro's template engine core class""" 
    variable_regex = r'\$\{((.*)(%s)([^}]*))*\}' 
    def __init__(self, string): 
     self.string = string 

    def __repr__(self): 
     pieces = self.string.split() 
     if len(pieces) > 3: 
      head = "%s ..." % " ".join(pieces[:3]) 
     else: 
      head = " ".join(pieces) 

     return u'<JTuroTemplate: "%s">' % (head) 

    def render(self, context): 
     new = unicode(self.string) 

     for key, value in context.items(): 
      variable_name = re.escape(key) 
      regex = re.compile(self.variable_regex % variable_name) 

      for match in regex.findall(new): 
       if match[0]: 
        replacement = match[0].replace(key, repr(value)) 
        new = new.replace('${%s}' % match[0], unicode(eval(replacement))) 

     return new 

class TestJTuroTemplate(unittest.TestCase): 
    def test_repr(self): 
     "a instance will be nicely represented" 
     jt = JTuroTemplate('my template') 
     self.assertEquals(repr(jt), '<JTuroTemplate: "my template">') 

    def test_repr_truncated(self): 
     "the python representation is truncated after 3 words" 

     jt = JTuroTemplate('such a long string template') 
     self.assertEquals(repr(jt), '<JTuroTemplate: "such a long ...">') 

    def test_solves_simple_variables(self): 
     "it solves simple variables" 

     jt = JTuroTemplate('my variable is ${var} == 4') 
     self.assertEquals(jt.render({'var': '4'}), 'my variable is 4 == 4') 

    def test_solves_variables_with_python_code(self): 
     "it solves variables with python code" 

     jt = JTuroTemplate('my variable is ${var + var} == 44') 
     self.assertEquals(jt.render({'var': '4'}), 'my variable is 44 == 44') 

if __name__ == '__main__': 
    unittest.main() 

很抱歉的长期职位,但我认为你可以试试这个工作流程:

  1. 写测试失败
  2. 运行并看它失败
  3. 编写代码测试再次通过
  4. 运行,看它传递
+0

感谢你的代码,这也需要一些学习。我认为正则表达式是一种可行的方法,但最大的问题是:使用执行大量正则表达式的模板引擎,流量大的网站会变得非常慢吗?再次感谢Gabriel对你的帖子 – jturo 2010-06-02 11:03:25

4

很好,因为你说你是一个Python菜鸟,而你书面方式从头开始一个新的MVC框架和模板引擎的唯一原因,是为了学习目的,你不应该关心性能恕我直言。

但是如果你决定在生产中加入某些东西,你应该考虑使用已经存在的模板引擎,比如jinja2,mako,genshi等等。

无论如何,如果你要玩,有轻量级web python框架内的一个很好的例子:http://github.com/breily/juno

和光速模板引擎在http://github.com/eklitzke/spitfire

快乐黑客!

+0

以及我不得不承认你有一个点。感谢您的链接和脚本。好东西玩和学习。 – jturo 2010-06-04 09:34:24