Verwenden Sie YAML mit Variablen


82

Sind Variablen in YAML-Dateien möglich? Zum Beispiel:

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

Wie kann in diesem Beispiel theme: name: defaultin anderen Einstellungen verwendet werden? Wie ist die Syntax?


Welche Sprache / Bibliothek verwenden Sie, um diese YAML zu analysieren? In YAML gibt es keine Standardmethode, aber vielleicht hat Ihre Bibliothek einige Tricks.
Jesse Beder


@CiroSantilli; 文件 六四 事件 法轮功 ;; eng verwandt, aber kein Duplikat. Beliebige Variablen werden in Standard-YAML nicht unterstützt, es sind jedoch Querverweise auf ganze Elemente aus dem YAML-Analysebaum verfügbar. Daher sind die Fragen etwas anders.
Dreftymac


Antworten:


106

Ich hatte dieselbe Frage und nach vielen Recherchen sieht es so aus, als wäre das nicht möglich .

Die Antwort von cgat ist auf dem richtigen Weg, aber Sie können solche Referenzen nicht wirklich verketten.

Hier sind die Dinge, die Sie mit "Variablen" in YAML tun können (die offiziell als "Knotenanker" bezeichnet werden, wenn Sie sie festlegen, und "Referenzen", wenn Sie sie später verwenden):

Definieren Sie einen Wert und verwenden Sie später eine genaue Kopie davon:

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

{ oder }

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.

Weitere Informationen finden Sie in diesem Abschnitt der Wiki-Seite zu YAML: http://en.wikipedia.org/wiki/YAML#References

Definieren Sie ein Objekt und verwenden Sie es später mit Änderungen:

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

Dies stammt direkt aus einer großartigen Demo hier: https://gist.github.com/bowsersenior/979804


1
Auch diese Frage ist im Wesentlichen ein Duplikat: stackoverflow.com/questions/2063616/…
benrugg

1
Was macht <<das Ich kann es nicht in der Dokumentation finden .
Hi-Angel

1
@ Hi-Angel YAML Merge Key Specification beantwortet die Frage, was zu <<tun ist.
Dreftymac

46

Nach einiger Suche habe ich eine sauberere Lösung gefunden, die den %Operator verwendet.

In Ihrer YAML-Datei:

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

In Ihrem Ruby-Code:

require 'yaml'

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

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

puts modified_content

Und die Ausgabe ist:

This is the foobar var : Hello World !

Wie @jschorr im Kommentar sagte, können Sie dem Wert in der Yaml-Datei auch mehrere Variablen hinzufügen:

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 }

Ausgabe :

The foo var is FOO and the bar var is BAR !

1
Toller Fund; Das Schöne ist, dass Sie auch mehrere Variablen ausführen können:% {var1: 'was auch immer', var2: 'anotherone'}.
Jschorr

2
Lesen Sie mehr über den %Operator der Ruby-Zeichenfolge: ruby-doc.org/core-2.2.3/String.html#method-i-25
Trantor Liu

Eine andere Möglichkeit besteht darin, das Yaml zu laden, wodurch Sie einen Hash in Rubin erhalten. Änderungen können am Hash vorgenommen und dann in die Datei zurückgeschrieben werden.
LeoOrion

Tolles Zeug. Funktioniert auch mit ReactJS + Webpack + Messageformat-Loader + React-Message-Context + YAML-Lösung. Es hat tatsächlich sofort funktioniert, eine Variable als Requisite zu verwenden: <Message id = {'textId'} foo = {'some text'} />
Arkadiusz Lendzian

3

Dies ist ein alter Beitrag, aber ich hatte ein ähnliches Bedürfnis und dies ist die Lösung, die ich gefunden habe. Es ist ein bisschen wie ein Hack, aber es funktioniert und könnte verfeinert werden.

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

Ein großer Nachteil ist, dass in das yaml-Dokument ein Variablenname (in diesem Fall "Daten") eingebaut wird, der möglicherweise vorhanden ist oder nicht. Vielleicht wäre eine bessere Lösung, $ zu verwenden und es dann vor ERB durch den Variablennamen in Ruby zu ersetzen. Außerdem wurde es gerade mit hashes2ostruct getestet, was eine Notation vom Typ data.theme.name ermöglicht, die für die Augen viel einfacher ist. Alles, was erforderlich ist, ist das Umschließen der YAML :: -Ladung damit

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

Dann kann Ihr YAML-Dokument so aussehen

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

Rails / Ruby-Frameworks können Vorlagen erstellen ... es wird häufig zum Laden von env-Variablen verwendet ...

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

Keine Ahnung, ob dies für Javascript-Frameworks funktioniert, da ich denke, dass das YML-Format eine Obermenge von json ist und davon abhängt, was die yml-Datei für Sie liest.

Wenn Sie die Vorlage wie diese oder die << >>oder die {{ }}Stile je nach Leser verwenden können, müssen Sie danach nur noch ...

In einer anderen yml-Datei ...

# boo.yml

development:
  fooz: foo

Auf diese Weise können Sie bei jeder dynamischen Einstellung grundsätzlich eine Variable als Referenz für die Originaldatei einfügen. Beim Lesen habe ich auch gesehen, dass Sie YML-Dateien als Objekte im laufenden Betrieb für mehrere Sprachen erstellen oder öffnen können. Auf diese Weise können Sie eine Datei erstellen und eine Reihe von YML-Dateien in einer Kette schreiben oder sie alle statisch auf die dynamisch erstellte Datei verweisen lassen.


0

Wenn Ihre Anforderung darin besteht, eine ersetzende Mehrfachvariable zu analysieren und sie dann als Hash / oder etwas anderes zu verwenden, können Sie so etwas tun

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

In das Yaml werden einfach solche Variablen eingefügt

"%{var_a}"
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.