简体   繁体   English

Mako模板变量名称

[英]Mako Template Variable Names

Is it it possible to get the names of the variables in a Mako Template before rendering? 是否可以在渲染之前获取Mako模板中的变量名称?

from mako.template import Template
bar = Template("${foo}")

# something like:
# >> print bar.fields()
# ['foo']

Use case: 使用案例:

We have configuration files whereby we specify the metadata from the database to be displayed on a webpage. 我们有配置文件,我们指定数据库中的元数据以显示在网页上。 The client can pick one of a few hundred different pieces of named metadata. 客户端可以选择几百个不同的命名元数据中的一个。 There are N slots the client can configure but we don't know in advance which pieces of metadata a particular client would like to have filled in on the form. 客户端可以配置N个插槽,但我们事先并不知道特定客户端希望在表单上填写哪些元数据。 Because if this when rendering the form we need to know, in advance, what variable names we need to pass for this clients template. 因为如果在渲染表单时我们需要提前知道我们需要为此客户端模板传递哪些变量名称。

We had thought of having a consistent dictionary with all possible values and passing that in each time but it was unworkable as new available fields are added frequently to the underlying pool of available metadata the client could pick. 我们曾想过拥有一个包含所有可能值的一致字典并在每次传递它但由于新的可用字段经常添加到客户端可以选择的基础可用元数据池中而无法工作。

Because of this we had hoped to use Mako to template the config files but I can't figure out how to determine with the field values in the template would be so that I can build a full-formed Context to pass to the template. 因此,我们希望使用Mako来模拟配置文件,但我无法弄清楚如何使用模板中的字段值来确定是否可以构建一个完整形式的Context以传递给模板。

Unfortunately there is no easy way to get the names of the variables from a template object. 遗憾的是,没有简单的方法可以从模板对象中获取变量的名称。

Fortunately there is the mako.codegen._Identifiers class and the sole purpose of its objects is to keep track of the variables during the compilation process. 幸运的是,有mako.codegen._Identifiers类,其对象的唯一目的是在编译过程中跟踪变量。

Unfortunately it is buried deep beneath the Mako API surface, and it is gone after the compilation is done. 不幸的是,它深埋在Mako API表面下方,在编译完成后它就消失了。

Fortunately you can get it without setting up everything Mako sets up when it compiles templates. 幸运的是,你可以在没有设置Mako在编译模板时设置的所有内容的情况下获得它。 All you need is the parse tree that you can get by using mako.lexer.Lexer . 您只需要使用mako.lexer.Lexer获得的解析树

Anyway here is the code: 无论如何这里是代码:

from mako import lexer, codegen


lexer = lexer.Lexer("${foo}", '')
node = lexer.parse()
# ^ The node is the root element for the parse tree.
# The tree contains all the data from a template
# needed for the code generation process

# Dummy compiler. _Identifiers class requires one
# but only interested in the reserved_names field
compiler = lambda: None         
compiler.reserved_names = set() 

identifiers = codegen._Identifiers(compiler, node)
# All template variables can be found found using this
# object but you are probably interested in the
# undeclared variables:
# >>> print identifiers.undeclared
# set(['foo'])

Chasing Mako variables is no fun. 追逐Mako变量并不好玩。 I knocked together this little function to extract the variables from a template - use & improve as you like. 我将这个小函数组合在一起从模板中提取变量 - 根据需要使用和改进。

    def ListMakoVariables(template):
        '''
        Extract Mako variables from template.
        '''
        start = 'XXXX${'
        stop = '}YYYY'
        makovars = []
        splitReady = template.replace('${',start).replace('}',stop)
        startParts = splitReady.split('XXXX')
        for startStr in startParts:
            if '}' in startStr:
                makovars.append(startStr.split('YYYY')[0])
        vars = set(makovars)
        return vars, makovars

FWIW, makovars are in-order, vars are unique but not in order. FWIW,makovars是有序的,vars是独特的但不是有序的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM