I have the following YAML file:
site:
title: My blog
domain: example.com
author1:
name: bob
url: /author/bob
author2:
name: jane
url: /author/jane
header_links:
about:
title: About
url: about.html
contact:
title: Contact Us
url: contactus.html
js_deps:
- cashjs
- jets
products:
product1:
name: Prod One
price: 10
product2:
name: Prod Two
price: 20
And I'd like a Bash, Python or AWK function or script that can take the YAML file above as input ($1
), and generate then execute the following code (or something exactly equivalent):
unset site_title
unset site_domain
unset site_author1
unset site_author2
unset site_header_links
unset site_header_links_about
unset site_header_links_contact
unset js_deps
site_title="My blog"
site_domain="example.com"
declare -A site_author1
declare -A site_author2
site_author1=(
[name]="bob"
[url]="/author/bob"
)
site_author2=(
[name]="jane"
[url]="/author/jane"
)
declare -A site_header_links_about
declare -A site_header_links_contact
site_header_links_about=(
[name]="About"
[url]="about.html"
)
site_header_links_contact=(
[name]="Contact Us"
[url]="contact.html"
)
site_header_links=(site_header_links_about site_header_links_contact)
js_deps=(cashjs jets)
unset products
unset product1
unset product2
declare -A product1
declare -A product2
product1=(
[name]="Prod One"
[price]=10
)
product2=(
[name]="Prod Two"
[price]=20
)
products=(product1 product2)
So, the logic is:
Go through the YAML, and create underscore concatenated variable names with string values, except at the last (bottom) level, where data should be created as an associative array or index array, wherever possible... Also, any assoc arrays created should be listed by name, in an indexed-array.
So, in other words:
wherever the last level of data can be turned into an associative array then it should be (
foo.bar.hash
=>${foo_bar_hash[@]}
wherever the last level of data can be turned into an indexed array then it should be (
foo.bar.list
=>${foo_bar_list[@]}
every assoc array should be listed by name in an indexed array which is named after its parent in the yaml data (see
products
in the example)else, just make an underscore concatenated var name and save the value as a string (
foo.bar.string
=>${foo_bar_string}
...The reason I need this specific Bash data structure is that I'm using a Bash-based templating system which requires it.
Once I have the function I need, I will be able to use the YAML data easily in my templates, like so:
{{site_title}}
...
{{#foreach link in site_header_links}}
<a href="{{link.url}}">{{link.name}}</a>
{{/foreach}}
...
{{#js_deps}}
{{.}}
{{/js_deps}}
...
{{#foreach item in products}}
{{item.name}}
{{item.price}}
{{/foreach}}
What I tried:
This is totally related to a previous question I asked:
This is so close, but I need an associative array of site_header_links
to be generated OK as well .. it fails because site_header_links
is nested too deep.
I would still love to use https://github.com/azohra/yaml.sh in the solution, as it would provide an easy handlebars-style lookup
rip-off for the templating system too :)
EDIT:
To be super clear: The solution cannot use pip
, virtualenv
, or any other external deps that need installing separately - it must be a self-contained script/func (like https://github.com/azohra/yaml.sh is) which can live inside the CMS project dir... or I wouldn't need to be here..
...
Hopefully, a nicely commented answer might help me avoid coming back here ;)