防止buildout中的变量替换

8 投票
3 回答
980 浏览
提问于 2025-04-15 12:56

有没有简单的方法可以让我们在 buildout 配置中使用的特殊字符不被替换成变量的值,而是保持原样?换句话说,我想要的是:

[part]
attribute = ${variable}

我并不想让 ${variable} 被替换,而是希望它保持原来的样子。

实际上,我遇到的具体问题并不在于 buildout 配置文件本身,而是在一个由 'collective.recipe.template' 处理的模板文件中。这个模板使用了和配置文件一样的变量替换机制。问题是,我想用作模板的文件已经在它自己的应用配置系统中使用了 '${variable}' 这种语法。

我找到的唯一解决办法是使用类似这样的方式:

[server-xml]
recipe = collective.recipe.template
input = templates/server.xml.in
output = ${product:build-directory}/conf/server.xml
dollar = $

然后在模板输入文件中写:

${dollar}{variable}

而不是:

${variable}

那样的内容。

这样做的目的是查找与模板相关的 'dollar' 属性,并将其替换为 '$'。

我本来希望能直接这样做:

\${variable}

或者甚至:

$${variable}

这样就不需要用一个虚假的属性来让它按照我想要的方式工作了。

从 buildout 的源代码来看,它匹配变量替换的方式似乎没有提供逃避机制。

如果确实没有办法,那么也许有人知道一个替代的模板方案,可以在 buildout 中进行变量扩展,同时提供一种逃避机制,以避免模板系统的扩展机制和文件中的字面数据之间的冲突。

3 个回答

3

${之间插入一个空的替代项,可以防止buildout把生成的文本当作一个buildout的替代项来处理。

buildout.cfg:

[server-xml]
recipe = collective.recipe.template
input = server.xml.in
output = server.xml
_ =

server.xml.in:

do no substitution $${_}{myvar} blah

server.xml:

do no substitution ${myvar} blah
5

从collective.recipe.template的1.7版本开始,你可以使用genshi文本模板,但从1.8版本开始,它变得更有用,因为修复了一些问题。

recipe = collective.recipe.template[genshi]:genshi
...
mymessage = Hello

所以输入文件看起来是这样的

The message in $${:mymessage} is: ${options['mymessage']}

genshi支持对美元符号进行转义,具体可以查看这个链接:http://genshi.edgewall.org/wiki/Documentation/templates.html#escaping

关于如何将这个配方与genshi一起使用的更多细节,可以查看这个链接:http://pypi.python.org/pypi/collective.recipe.template#genshi-text-templates

6

我觉得你对buildout变量替换代码的分析是对的。这个代码是collective.recipe.template依赖的。确实没有办法对${section:variable}这种变量替换进行转义,而你提出的用${dollar}替代的办法是我能想到的最好的解决方案。

当然,你也可以向zc.buildout团队提议一个补丁,来增加对变量替换语法转义的支持。:-)

撰写回答