Użyj YAML ze zmiennymi

82

Czy możliwe są zmienne w plikach YAML? Na przykład:

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

W tym przykładzie, jak można theme: name: defaultgo używać w innych ustawieniach? Jaka jest składnia?

piwowar
źródło
Jakiego języka / biblioteki używasz do analizowania tego YAML? Nie ma standardowego sposobu na zrobienie tego w YAML, ale może twoja biblioteka ma kilka sztuczek.
Jesse Beder
1
możliwy duplikat: stackoverflow.com/questions/2063616/…
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
@CiroSantilli 巴拿馬 文件 六四 事件 法轮功 ;; blisko spokrewnione, ale nie jest duplikatem. Zmienne arbitralne nie są obsługiwane w standardowym YAML, jednak dostępne są odsyłacze do całych elementów z drzewa analizy YAML. Dlatego pytania są nieco inne.
dreftymac
Zobacz też: stackoverflow.com/a/41620747/42223
dreftymac

Odpowiedzi:

107

Miałem to samo pytanie i po wielu badaniach wygląda na to, że nie jest to możliwe .

Odpowiedź z cgat jest na dobrej drodze, ale w rzeczywistości nie można łączyć takich odniesień.

Oto rzeczy, które możesz zrobić ze „zmiennymi” w YAML (które są oficjalnie nazywane „kotwicami węzłów”, gdy je ustawiasz i „odniesieniami”, gdy używasz ich później):

Zdefiniuj wartość i użyj jej dokładnej kopii później:

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

{lub}

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.

Aby uzyskać więcej informacji, zobacz tę sekcję strony wiki o YAML: http://en.wikipedia.org/wiki/YAML#References

Zdefiniuj obiekt i użyj go później z modyfikacjami:

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

To pochodzi bezpośrednio z doskonałego demo tutaj: https://gist.github.com/bowsersenior/979804

benrugg
źródło
1
Również to pytanie jest w zasadzie duplikatem: stackoverflow.com/questions/2063616/…
benrugg
1
Co robi <<? Nie mogę znaleźć tego w dokumentacji .
Hi-Angel,
1
@ Hi-Angel Specyfikacja klucza scalającego YAML odpowiada na pytanie, co robi <<?
dreftymac
46

Po kilku poszukiwaniach znalazłem czystsze rozwiązanie, w którym używa się %operatora.

W pliku YAML:

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

W swoim kodzie ruby:

require 'yaml'

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

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

puts modified_content

A wynik to:

This is the foobar var : Hello World !

Jak powiedział @jschorr w komentarzu, możesz również dodać wiele zmiennych do wartości w pliku Yaml:

Yaml:

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

Rubin:

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

Wynik :

The foo var is FOO and the bar var is BAR !
cebula
źródło
1
Świetne znalezisko; fajną rzeczą jest to, że możesz też zrobić wiele zmiennych:% {var1: 'cokolwiek', var2: 'inny'}.
jschorr
2
Przeczytaj więcej o %operatorze łańcucha Ruby: ruby-doc.org/core-2.2.3/String.html#method-i-25
Trantor Liu
Innym sposobem jest załadowanie yamla, który da ci haszysz w rubinie. Zmiany można wprowadzić w hashu, a następnie zapisać z powrotem do pliku.
leoOrion
Świetne rzeczy. Działa również z ReactJS + Webpack + messageformat-loader + responsive-message-context + rozwiązanie YAML. Wykorzystanie zmiennej jako rekwizytu faktycznie działało od razu po wyjęciu z pudełka: <Message id = {'textId'} foo = {'some text'} />
Arkadiusz Lendzian
3

To jest stary post, ale miałem podobną potrzebę i to jest rozwiązanie, które wymyśliłem. To trochę hack, ale działa i można go ulepszyć.

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

Dużym minusem jest to, że wbudowuje on w dokument yaml nazwę zmiennej (w tym przypadku „dane”), która może istnieć lub nie. Być może lepszym rozwiązaniem byłoby użycie znaku $, a następnie zastąpienie go nazwą zmiennej w Rubim przed ERB. Po prostu przetestowałem używanie hashes2ostruct, który pozwala na zapis typu data.theme.name, co jest znacznie łatwiejsze dla oczu. Wszystko, co jest wymagane, to opakować tym plik YAML :: load

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

Wtedy twój dokument YAML może wyglądać tak

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
Ben
źródło
1

jeśli twoje wymaganie jest takie jak parsowanie zastępowania wielu zmiennych, a następnie użycie ich jako hash / lub cokolwiek innego, możesz zrobić coś takiego

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

wewnątrz yamla po prostu umieść takie zmienne

"%{var_a}"
mithucste30
źródło
0

Railsy / frameworki ruby ​​są w stanie wykonać pewne szablony ... jest często używany do ładowania zmiennych env ...

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

Nie mam pojęcia, czy to działa dla frameworków javascript, ponieważ myślę, że format YML jest nadzbiorem json i zależy to od tego, co czyta plik yml dla Ciebie.

Jeśli możesz użyć takiego szablonu << >>lub {{ }}stylów lub w zależności od czytelnika, po prostu ...

W innym pliku yml ...

# boo.yml

development:
  fooz: foo

Co pozwala w zasadzie wstawiać zmienną jako odniesienie do oryginalnego pliku za każdym razem, gdy jest on ustawiany dynamicznie. Podczas czytania zauważyłem również, że możesz tworzyć lub otwierać pliki YML jako obiekty w locie dla kilku języków, co pozwala na tworzenie plików i łańcuchów, zapisywanie serii plików YML lub po prostu ich statyczne wskazywanie na dynamicznie utworzony.

Mirv - Matt
źródło