Используйте YAML с переменными
Возможны ли переменные в файлах YAML? Например:
theme:
name: default
css_path: compiled/themes/$theme.name
layout_path: themes/$theme.name
В этом примере, как можно theme: name: default
использоваться в других настройках? Какой синтаксис?
6 ответов
У меня был тот же вопрос, и после долгих исследований похоже, что это невозможно.
Ответ от 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: http://en.wikipedia.org/wiki/YAML
Определите объект и используйте его с изменениями позже:
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
После некоторого поиска я нашел более чистое решение, которое использует %
оператор.
В вашем файле 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 !
Это старый пост, но у меня была похожая потребность, и это решение, которое я придумал. Это что-то вроде хака, но это работает и может быть улучшено.
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 имя переменной (в данном случае "данные"), которая может существовать или не существовать. Возможно, лучшим решением было бы использовать $, а затем заменить его именем переменной в Ruby до ERB. Кроме того, только что протестировал, используя 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
Если ваше требование похоже на синтаксический анализ заменяющей нескольких переменных, а затем использовать ее как хэш / или что-то еще, вы можете сделать что-то вроде этого
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}"
Вот как я смог настроить файлы yaml для ссылки на переменную.
У меня есть поля корневого уровня, которые используются в качестве переменных шаблона внутри
values.yaml
values.yaml
.....
databaseUserPropName: spring.datasource.username
databaseUserName: sa
.....
secrets:
type: Opaque
name: dbservice-secrets
data:
- name: "{{ .Values.databaseUserPropName }}"
value: "{{ .Values.databaseUserName }}"
.....
При ссылке на эти значения в
secret.yaml
, мы бы использовали функцию tpl, используя синтаксис
{{ tpl TEMPLATE_STRING VALUES }}
secret.yaml
при использовании внутри диапазона i: e итерация
{{ range .Values.deployments.secrets.data }}
{{ tpl .name $ }}: "{{ tpl .value $ }}"
{{ end }}
при прямой ссылке на переменную
{{ tpl .Values.deployments.secrets.data.name . }}
{{ tpl .Values.deployments.secrets.data.value . }}
$ - это глобальная переменная, всегда указывающая на корневой контекст. - эта переменная будет указывать на корневой контекст в зависимости от того, где она использовалась.
Rails / ruby фреймворки могут создавать шаблоны... это часто используется для загрузки переменных env...
# fooz.yml
foo:
bar: <%= $ENV[:some_var] %>
Не знаю, работает ли это для фреймворков javascript, так как я думаю, что формат YML - это расширенный набор json, и это зависит от того, что читает файл yml для вас.
Если вы можете использовать шаблон как этот или << >>
или {{ }}
стили в зависимости от вашего читателя, после этого вы просто...
В другом файле YML...
# boo.yml
development:
fooz: foo
Что позволяет вам в основном вставлять переменную в качестве ссылки на исходный файл каждый раз, когда она устанавливается динамически. При чтении я также увидел, что вы можете создавать или открывать файлы YML в виде объектов на лету для нескольких языков, что позволяет вам создавать файлы и цепочки, записывать серии файлов YML или просто статически указывать на динамически создаваемые файлы.