Используйте YAML с переменными


82

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

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

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


Какой язык / библиотеку вы используете для анализа этого YAML? В YAML нет стандартного способа сделать это, но, возможно, в вашей библиотеке есть некоторые хитрости.
Джесси Бедер,


@CiroSantilli 巴拿馬 文件 六四 事件 法轮功 ;; близкородственные, но не дублирующие. Произвольные переменные не поддерживаются в стандартном YAML, однако доступны перекрестные ссылки на целые элементы из дерева синтаксического анализа YAML. Поэтому вопросы немного другие.
dreftymac


Ответы:


107

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

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


1
Кроме того, этот вопрос по сути является дубликатом: stackoverflow.com/questions/2063616/…
benrugg

1
Что <<делать? Кажется, я не могу найти его в документации .
Hi-Angel

1
Спецификация ключа слияния @ Hi-Angel YAML отвечает на вопрос, что делает <<?
dreftymac

46

После некоторых поисков я нашел более чистое решение, в котором используется %оператор.

В вашем 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 !

1
Отличная находка; приятно то, что вы также можете использовать несколько переменных:% {var1: 'something', var2: 'anotherone'}.
jschorr

2
Подробнее об %операторе строки Ruby: ruby-doc.org/core-2.2.3/String.html#method-i-25
Trantor Liu

Другой способ - загрузить yaml, который даст вам хэш в рубине. Изменения могут быть внесены в хеш, а затем записаны обратно в файл.
leoOrion

Качественный товар. Также работает с ReactJS + Webpack + messageformat-loader + response-message-context + YAML. На самом деле, использование переменной в качестве опоры сработало из коробки: <Message id = {'textId'} foo = {'some text'} />
Аркадиуш Лендзян

3

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

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

1

если ваше требование похоже на синтаксический анализ заменяющей нескольких переменных, а затем использовать ее как хэш / или что-то еще, вы можете сделать что-то вроде этого

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}"

0

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

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

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

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

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

# boo.yml

development:
  fooz: foo

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.