web-dev-qa-db-fra.com

Utiliser YAML avec des variables

Des variables dans les fichiers YAML sont-elles possibles? Par exemple:

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

Dans cet exemple, comment theme: name: default Peut-il être utilisé dans d'autres paramètres? Quelle est la syntaxe?

73
brewster

J'avais la même question et après de nombreuses recherches, il semble que ce ne soit pas possible .

La réponse de cgat est sur la bonne voie, mais vous ne pouvez pas concaténer de telles références.

Voici ce que vous pouvez faire avec les "variables" dans YAML (appelées officiellement "ancres de nœuds" lorsque vous les définissez et "références" lorsque vous les utiliserez plus tard):

Définissez une valeur et utilisez-en une copie exacte ultérieurement:

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

{ ou }

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.

Pour plus d'informations, consultez cette section de la page wiki sur YAML:http://en.wikipedia.org/wiki/YAML#References

Définissez un objet et utilisez-le avec des modifications ultérieures:

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

Ceci est tiré directement d'une grande démo ici:https://Gist.github.com/bowsersenior/979804

98
benrugg

Après quelques recherches, j'ai trouvé une solution plus propre qui utilise le % opérateur.

Dans votre fichier YAML:

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

Dans votre code Ruby:

require 'yaml'

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

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

puts modified_content

Et le résultat est:

This is the foobar var : Hello World !

Comme @jschorr l'a dit dans le commentaire, vous pouvez également ajouter plusieurs variables à la valeur du fichier 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 }

Sortie:

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

Ceci est un ancien post, mais j'avais un besoin similaire et c'est la solution que j'ai proposée. C'est un peu un bidouillage, mais cela fonctionne et pourrait être affiné.

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

Un gros inconvénient est qu’il crée dans le document yaml un nom de variable (dans le cas présent, "data") qui peut ou non exister. Une meilleure solution consisterait peut-être à utiliser $, puis à la remplacer par le nom de la variable dans Ruby avant ERB. En outre, cela vient d’être testé avec hashes2ostruct , qui autorise data.theme. Notation de type .name qui est beaucoup plus facile pour les yeux. Tout ce qui est nécessaire est d’envelopper le YAML :: load avec

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

Ensuite, votre document YAML peut ressembler à ceci

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
3
Ben

Rails/Ruby peuvent faire des templates ... il est souvent utilisé pour charger des variables env ...

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

Aucune idée si cela fonctionne pour les frameworks javascript car je pense que le format YML est un sur-ensemble de json et cela dépend de ce qui lit le fichier yml pour vous.

Si vous pouvez utiliser le modèle comme ça ou le << >> ou la {{ }} styles en fonction de votre lecteur, après que vous venez ...

Dans un autre fichier yml ...

# boo.yml

development:
  fooz: foo

Ce qui vous permet d'insérer fondamentalement une variable en tant que référence du fichier d'origine à chaque fois que celle-ci est définie dynamiquement. En lisant, je voyais aussi que vous pouvez créer ou ouvrir des fichiers YML en tant qu’objets à la volée pour plusieurs langues, ce qui vous permet de créer un fichier et d’écrire une série de fichiers YML ou tout simplement de les faire pointer de manière statique vers le fichier créé de manière dynamique.

0
Mirv - Matt