hygen
hygen copied to clipboard
How to load local variables from JSON?
Thanks for the great library.
I can read variable values from CLI argument or prompt parameter. But I have lots of variables, so I have to keep in a separate JSON file.
Is there any way to load/read that JSON file and pass as local variables to the templates?
add an index.js file in your _templates/<your generator>/<your action
use something like this untested code. pass --json path/of/file
// _templates/<generator>/<action>/index.js
const fs = require('fs')
module.exports = {
params: ({ args }) => {
let jsonData = {}
if (args.json) {
let rawdata = fs.readFileSync(args.json);
jsonData = JSON.parse(rawdata);
}
return {
...args,
...jsonData
}
},
}
I have added your code in my index.js and put that in my action directory. Now how can I access that json? in the template file when I put variable json, I get the path in the generated file, not the contents of the json. Did I do something wrong?
The return value of the params function get added to the template as variables.
if the json above looks like {"color": "white","background":"purple"} and is exported as above, then in your template you can <%= color %> and <%= background %>
Another point of confusion may be the spread operator ...jsonData That adds all of the key value pairs to the object being returned. If it were returned as
return {
...args,
jsonData,
}
You'd use it like <%= jsonData.color %>.
Also, args is everything you passed in via the command line.
hygen jg page --name PinkFloyd --container band --route '/bands/pink_floyd' args = {name: 'PinkFloyd', container: 'band', route: '/bands/pink_floyd'}`
I'm interested in the same thing but I'm fairly certain my code in index.js isn't running. (I've tried the suggested code. Logging consoles, throwing errors, etc..)
cmd: hygen StackEntity new Catalog prompt: favorite color: blahhhh result: Loaded templates: xxx\Frontend_templates ReferenceError: ejs:7 5| 6| //endpoint calls go here
7| <%=jsonData.color%> 8| <%=jsonData.background%> 9| } 10|
jsonData is not defined Hygen v4.0.11
File structure is below.
add an index.js file in your
_templates/<your generator>/<your actionuse something like this untested code. pass--json path/of/file// _templates/<generator>/<action>/index.js const fs = require('fs') module.exports = { params: ({ args }) => { let jsonData = {} if (args.json) { let rawdata = fs.readFileSync(args.json); jsonData = JSON.parse(rawdata); } return { ...args, ...jsonData } }, }
but prompt doesn't work
Is there any workaround for this?
I found a simplier, uglier but still acceptable workaround for this: I use the initial property of prompt.js to pass more complex json data, so you can access the data in your template playing with JSON.parse() and JSON.stringify():
For example in my prompt.js I write the following JSON (non-sense, just for the show):
// prompt.js
module.exports = [
{
type: "input",
name: "filename",
message: "Type file name:",
}
{
type: "input",
name: "modelStr",
message: "This is the json data you wanna pass, just confirm:",
initial: `[
{ "label": "title", "id": 1, "fr": "titre", "required": true },
{ "label": "order", "id": 2, "fr": "ordre", "required": false },
{ "label": "link", "id": 3, "fr": "lien", "required": true }
]`
}
then in my template:
// mytemplate.ejs.t
---
to: <%= filename %>.js
---
// this will build a proper array from the input string
<% model = JSON.parse(modelStr) %>
// Then I can loop on my array to properly build my file as I want,
// In the example below; NOTE THAT I USE "<%-" INSTEAD OF <%=" so
// I can display strings with quotes or double quotes (otherwise I got strings like #&32.
// Since from json input we always need quotes for strings, note how I remove
// them when needed with .replace(/"/g, "")
const myObject = {
<% for (let i=0; i<model2.length; i++) { let item = model2[i]%>
<%-JSON.stringify(item.label).replace(/"/g, "")%> : { id : <%-JSON.stringify(item.id)%>, fr: <%-JSON.stringify(item.fr)%>, required: <%-JSON.stringify(item.required)%> },
<% } %>
}
Output will be:
const myObject = {
title : { id : 1, fr: "titre", required: true },
order : { id : 2, fr: "ordre", required: false },
link : { id : 3, fr: "lien", required: true },
}
At least, you can pass as much json data this way by additionning more inputs to the promps.js