Використовуйте 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


Дивіться також: stackoverflow.com/a/41620747/42223
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
@ Специфікація ключа злиття YAML Hi-Angel відповідає на питання, що <<робити?
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: 'what', var2: 'anotherone'}.
jschorr

2
Детальніше про %оператора рядка Ruby читайте
Трантор Лю

Інший спосіб - завантажити ямл, який дасть вам хеш у рубіні. Зміни можна внести в хеш, а потім записати назад у файл.
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.