97

YAML 文件中的变量是否可能?例如:

theme:
  name: default
  css_path: compiled/themes/$theme.name
  layout_path: themes/$theme.name

在此示例中,如何theme: name: default在其他设置中使用?语法是什么?

4

6 回答 6

113

我有同样的问题,经过大量研究,看起来这是不可能的

cgat 的答案是正确的,但你实际上不能像这样连接引用。

以下是您可以使用 YAML 中的“变量”执行的操作(设置它们时正式称为“节点锚点”,稍后使用它们时称为“引用”):

定义一个值并稍后使用它的精确副本:

default: &default_title This Post Has No Title
title: *default_title

{ 或者 }

example_post: &example
  title: My mom likes roosters
  body: Seriously, she does. And I don't know when it started.
  date: 8/18/2012
first_post: *example
second_post:
  title: whatever, etc.

有关更多信息,请参阅有关 YAML 的 wiki 页面的此部分: http ://en.wikipedia.org/wiki/YAML#References

定义一个对象并在稍后修改后使用它:

default: &DEFAULT
  URL:          stooges.com
  throw_pies?:  true  
  stooges:  &stooge_list
    larry:  first_stooge
    moe:    second_stooge
    curly:  third_stooge

development:
  <<: *DEFAULT
  URL:      stooges.local
  stooges: 
    shemp: fourth_stooge

test:
  <<: *DEFAULT
  URL:    test.stooges.qa
  stooges: 
    <<: *stooge_list
    shemp: fourth_stooge

这直接取自这里的一个很棒的演示: https ://gist.github.com/bowsersenior/979804

于 2013-09-18T16:03:20.030 回答
49

经过一番搜索,我找到了一个使用%运算符的更清洁的解决方案。

在您的 YAML 文件中:

key : 'This is the foobar var : %{foobar}'

在您的红宝石代码中:

require 'yaml'

file = YAML.load_file('your_file.yml')

foobar = 'Hello World !'
content = file['key']
modified_content = content % { :foobar => foobar }

puts modified_content

输出是:

This is the foobar var : Hello World !

正如@jschorr 在评论中所说,您还可以在 Yaml 文件中的值中添加多个变量:

亚毫升:

key : 'The foo var is %{foo} and the bar var is %{bar} !'

红宝石:

# ...
foo = 'FOO'
bar = 'BAR'
# ...
modified_content = content % { :foo => foo, :bar => bar }

输出 :

The foo var is FOO and the bar var is BAR !
于 2013-12-09T10:05:38.177 回答
4

这是一篇旧帖子,但我有类似的需求,这是我想出的解决方案。这有点像黑客,但它可以工作并且可以改进。

require 'erb'
require 'yaml'

doc = <<-EOF
  theme:
  name: default
  css_path: compiled/themes/<%= data['theme']['name'] %>
  layout_path: themes/<%= data['theme']['name'] %>
  image_path: <%= data['theme']['css_path'] %>/images
  recursive_path: <%= data['theme']['image_path'] %>/plus/one/more
EOF

data = YAML::load("---" + doc)

template = ERB.new(data.to_yaml);
str = template.result(binding)
while /<%=.*%>/.match(str) != nil
  str = ERB.new(str).result(binding)
end

puts str

一个很大的缺点是它在 yaml 文档中构建了一个可能存在也可能不存在的变量名称(在本例中为“数据”)。也许更好的解决方案是使用 $,然后用 ERB 之前的 Ruby 中的变量名替换它。此外,刚刚使用hashes2ostruct进行了测试,它允许 data.theme.name 类型表示法,这在眼睛上更容易。所需要做的就是用这个包装 YAML::load

data = hashes2ostruct(YAML::load("---" + doc))

然后你的 YAML 文档看起来像这样

doc = <<-EOF
  theme:
  name: default
  css_path: compiled/themes/<%= data.theme.name %>
  layout_path: themes/<%= data.theme.name %>
  image_path: <%= data.theme.css_path %>/images
  recursive_path: <%= data.theme.image_path %>/plus/one/more
EOF
于 2011-08-29T20:24:15.540 回答
3

This is how I was able to configure yaml files to refer to variable.

I have values.yaml where we have root level fields which are used as template variables inside values.yaml

values.yaml

.....  
databaseUserPropName: spring.datasource.username  
databaseUserName: sa  
.....  
secrets:
    type: Opaque  
    name: dbservice-secrets  
    data:  
      - name: "{{ .Values.databaseUserPropName }}"  
        value: "{{ .Values.databaseUserName }}"  
.....

When referencing these values in secret.yaml, we would use tpl function using syntax {{ tpl TEMPLATE_STRING VALUES }}

secret.yaml

when using inside range i:e iteration

  {{ range .Values.deployments.secrets.data }}
    {{ tpl .name $ }}: "{{ tpl .value $ }}"
  {{ end }}

when directly referring as variable

  {{ tpl .Values.deployments.secrets.data.name . }}
  {{ tpl .Values.deployments.secrets.data.value . }}

$ - this is global variable and will always point to the root context . - this variable will point to the root context based on where it used.

于 2021-01-21T06:21:13.787 回答
2

如果您的要求就像解析一个替换的多个变量,然后将其用作哈希/或任何东西,那么您可以做这样的事情

require 'yaml'
require 'json'
yaml = YAML.load_file("xxxx.yaml")
blueprint = yaml.to_json % { var_a: "xxxx", var_b: "xxxx"}
hash = JSON.parse(blueprint)

在yaml里面放这样的变量

"%{var_a}"
于 2020-07-28T09:45:02.987 回答
1

Rails / ruby​​ 框架能够做一些模板化......它经常用于加载环境变量......

# fooz.yml
  foo:
    bar: <%= $ENV[:some_var] %>

不知道这是否适用于 javascript 框架,因为我认为 YML 格式是 json 的超集,它取决于为您读取 yml 文件的内容。

如果您可以使用这样的模板或取决于您的读者<< >>的样式,那么您只需...{{ }}

在另一个 yml 文件中...

# boo.yml

development:
  fooz: foo

这允许您基本上插入一个变量作为您每次动态设置的原始文件的引用。在阅读时,我还看到您可以动态创建或打开 YML 文件作为几种语言的对象,这允许您创建文件并链式编写一系列 YML 文件,或者只是让它们都静态指向动态创建的文件。

于 2019-03-11T22:42:51.587 回答