Usa YAML con variables

82

¿Son posibles las variables dentro de los archivos YAML? Por ejemplo:

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

En este ejemplo, ¿cómo se theme: name: defaultpuede utilizar en otros entornos? Cual es la sintaxis?

cervecero
fuente
¿Qué idioma / biblioteca está utilizando para analizar este YAML? No hay una forma estándar de hacer esto en YAML, pero tal vez su biblioteca tenga algunos trucos.
Jesse Beder
1
posible duplicado de: stackoverflow.com/questions/2063616/…
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
@CiroSantilli 巴拿馬 文件 六四 事件 法轮功 ;; estrechamente relacionados, pero no un duplicado. Las variables arbitrarias no se admiten en YAML estándar, sin embargo, hay referencias cruzadas a elementos completos del árbol de análisis YAML disponibles. Por tanto, las preguntas son ligeramente diferentes.
dreftymac
Ver también: stackoverflow.com/a/41620747/42223
dreftymac

Respuestas:

106

Tenía la misma pregunta y, después de mucha investigación, parece que no es posible .

La respuesta de cgat está en el camino correcto, pero en realidad no puede concatenar referencias como esa.

Aquí hay cosas que puede hacer con "variables" en YAML (que se denominan oficialmente "anclajes de nodo" cuando las establece y "referencias" cuando las usa más adelante):

Defina un valor y use una copia exacta de él más tarde:

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

{o}

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.

Para obtener más información, consulte esta sección de la página wiki sobre YAML: http://en.wikipedia.org/wiki/YAML#References

Defina un objeto y utilícelo con modificaciones más adelante:

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

Esto se tomó directamente de una gran demostración aquí: https://gist.github.com/bowsersenior/979804

Benrugg
fuente
1
Además, esta pregunta es esencialmente un duplicado: stackoverflow.com/questions/2063616/…
benrugg
1
¿Qué <<hacer? Parece que no puedo encontrarlo en la documentación .
Hi-Angel
1
@ Hi-Angel YAML Merge Key Specification responde a la pregunta ¿qué hace <<?
dreftymac
46

Después de buscar, encontré una solución más limpia que usa el %operador.

En su archivo YAML:

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

En tu código ruby:

require 'yaml'

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

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

puts modified_content

Y la salida es:

This is the foobar var : Hello World !

Como dijo @jschorr en el comentario, también puede agregar varias variables al valor en el archivo Yaml:

Yaml:

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

Rubí:

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

Salida:

The foo var is FOO and the bar var is BAR !
cebolla
fuente
1
Gran hallazgo; lo bueno es que también puedes hacer múltiples variables:% {var1: 'lo que sea', var2: 'otro'}.
jschorr
2
Lea más sobre el %operador de la cadena Ruby: ruby-doc.org/core-2.2.3/String.html#method-i-25
Trantor Liu
Otra forma es cargar el yaml, que te dará un hash en ruby. Se pueden realizar cambios en el hash y luego volver a escribir en el archivo.
leoOrion
Buena cosa. Funciona también con ReactJS + Webpack + messageformat-loader + react-message-context + solución YAML. De hecho, funcionó fuera de la caja para usar la variable como prop: <Message id = {'textId'} foo = {'some text'} />
Arkadiusz Lendzian
3

Esta es una publicación antigua, pero tenía una necesidad similar y esta es la solución que se me ocurrió. Es un truco, pero funciona y podría perfeccionarse.

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

Una gran desventaja es que incorpora en el documento yaml un nombre de variable (en este caso, "datos") que puede o no existir. Quizás una mejor solución sería usar $ y luego sustituirlo por el nombre de la variable en Ruby antes de ERB. Además, solo se probó usando hashes2ostruct que permite la notación de tipo data.theme.name, que es mucho más fácil para los ojos. Todo lo que se requiere es envolver el YAML :: load con esto

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

Entonces su documento YAML puede verse así

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
fuente
0

Los frameworks Rails / ruby ​​pueden hacer algunas plantillas ... se usa con frecuencia para cargar variables env ...

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

No tengo idea de si esto funciona para los marcos de JavaScript, ya que creo que el formato YML es un superconjunto de json y depende de lo que lea el archivo yml por usted.

Si puede usar la plantilla así << >>o los {{ }}estilos o según su lector, después de eso solo ...

En otro archivo yml ...

# boo.yml

development:
  fooz: foo

Lo que le permite básicamente insertar una variable como referencia en ese archivo original cada vez que se configura dinámicamente. Al leer, también vi que puede crear o abrir archivos YML como objetos sobre la marcha para varios idiomas, lo que le permite crear un archivo y escribir en cadena una serie de archivos YML o simplemente hacer que todos apunten estáticamente al creado dinámicamente.

Mirv - Matt
fuente
0

si su requisito es como analizar una variable múltiple de reemplazo y luego usarla como un hash / o cualquier otra cosa, entonces puede hacer algo como esto

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

dentro del yaml solo ponga variables como esta

"%{var_a}"
mithucste30
fuente