2010-11-29 69 views
2

能編譯或還原Jinja2 AST的一部分嗎?Jinja2的編譯部分AST

例如,是否可以從模板中提取的節點列表中調用jinja2.environmentjinja2.compiler.generate或某個等價的函數或方法?

例如,給定的模板y.html

avant-tag 
{% xyz %} 
tag content {{ 3 + 5 }} 
{% endxyz %} 
apres-tag 

和延伸y.py

# -*- coding: utf-8 -*- 
from jinja2 import nodes, Environment, FileSystemLoader 
from jinja2.ext import Extension 

class YExtension(Extension): 
    tags = set(['y']) 

    def __init__(self, environment): 
     super(YExtension, self).__init__(environment) 

    def parse(self, parser): 
     tag = parser.stream.next() 
     body = parser.parse_statements(['name:endy'], drop_needle=True) 
     return nodes.Const("<!-- slurping: %s -->" % str(body)) 

env = Environment(
    loader  = FileSystemLoader('.'), 
    extensions = [YExtension], 
    ) 

print env.get_template('x.html').render() 

運行python y.py導致的預期輸出:

avant-tag 
<!-- slurping: [Output(nodes=[TemplateData(data=u'\n tag-content '), 
    Add(left=Const(value=3), right=Const(value=5)), 
    TemplateData(data=u'\n ')])] --> 
sous-tag 

parse方法,如何可以:

  1. 編譯body爲unicode(即, tag-content 8);或者可選地
  2. body恢復到其原始來源(即tag-content {{ 3 + 5 }})。

作爲背景的問題,這個問題涉及兩種現有問題:

  1. Jinja2 compile extension after includes;和
  2. Insert javascript at top of including file in Jinja 2

謝謝您的閱讀。

布賴恩

回答

1

編譯成Unicode尚無法在parse()方法,因爲你沒有提供該點的背景下。你可以繞過它,但它可能不是最好的方式。

請注意,parse()步驟通常只在html文件上執行一次,之後它將使用解析的字節碼來呈現模板。給定一個環境可以呈現解析步驟的結果。

你根本沒有可用的情況下出現,並獲得在那裏的背景下...相當困難;)

要獲得原始的源然而......沒有黑客不容易得多,但黑客是不是太糟糕;)

class YExtension(Extension): 
    tags = set(['y']) 

    def preprocess(self, source, name, filename=None): 
     # insert some code here that replaces '{% xyz %}foo bar{% endxyz %}' 
     # with something like: '{% xyz %}foo bar{% raw %}foo bar{% endraw %}{% endxyz %}' 
     return source 

在此之後,你可以閱讀從{% raw %}節點的文本作爲value。確保在此之後將其垃圾清除,否則它會顯示在您的模板中。

+0

謝謝WoLpH。我認爲這回答我的問題。我認爲唯一剩下的問題是在給定環境的情況下是否有方法呈現提取的結果。 – 2010-11-30 01:25:23