Используйте YAML с переменными - PullRequest
72 голосов
/ 11 ноября 2010

Возможны ли переменные в файлах YAML? Например:

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

В этом примере, как theme: name: default можно использовать в других настройках? Какой синтаксис?

Ответы [ 4 ]

95 голосов
/ 18 сентября 2013

У меня был тот же вопрос, и после долгих исследований похоже, что невозможно .

Ответ от 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#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

42 голосов
/ 09 декабря 2013

После некоторого поиска я нашел более чистое решение, использующее оператор %.

В вашем файле 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:

Yaml:

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

Ruby:

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

Вывод:

The foo var is FOO and the bar var is BAR !
3 голосов
/ 30 августа 2011

Это старый пост, но у меня была похожая потребность, и это решение, которое я придумал.Это что-то вроде хака, но это работает и может быть улучшено.

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 имя переменной (в данном случае «data»), которая можетили может не существовать.Возможно, лучшим решением было бы использовать $, а затем заменить его именем переменной в 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
0 голосов
/ 12 марта 2019

Rails / ruby ​​фреймворки могут создавать шаблоны ... это часто используется для загрузки переменных env ...

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

Не знаю, работает ли это для фреймворков javascript, так как я думаю, что формат YMLрасширенный набор json, и это зависит от того, что читает для вас файл yml.

Если вы можете использовать такой шаблон или стили << >> или {{ }} в зависимости от вашего читателя, после этого вы просто...

В другом файле yml ...

# boo.yml

development:
  fooz: foo

, который позволяет в основном вставлять переменную в качестве ссылки на исходный файл каждый раз, когда она устанавливается динамически.При чтении я также увидел, что вы можете создавать или открывать файлы YML в виде объектов на лету для нескольких языков, что позволяет создавать файлы и цепочки, записывать серии файлов YML или просто статически указывать на динамически создаваемые файлы.

...