nogridbag nogridbag - 4 months ago 25
JSON Question

JSON Templating Library - adding dynamic elements to static JSON files

In our Grails app, our navigation menu is client-specific and is returned to our SPA as JSON. We have a requirement to store these menu configuration as human editable files so they're easy to maintain and diff across clients (it's not something that needs to scale - we're talking less than 10 customized menus).

If it was completely static, we could simply use JSON files and be done with it.

[
"id": 1,
"text": "Menu Item 1",
"children": [...],
, ...
]


However, there are some minimal dynamic elements and I was curious if there were JSON templating libraries like there are for HTML.

[{
"for": "user in users"
"userId": {{user.id}}
"text": "Nav Item 1",
"children": [
{
"parentUserId": {{user.id}}
"text": "Child Nav Item"
}

]},
, {...}, ...
]





Output:

[{
"userId": "bob"
"text": "Nav Item 1",
"children": [
{
"parentUserId": "bob"
"text": "Child Nav Item"
}
]
}, {
"userId": "admin"
"text": "Nav Item 1",
"children": [
{
"parentUserId": "admin"
"text": "Child Nav Item"
}
]
}
]


So basically the requirement would be to repeat deep JSON objects (like angular's ng-repeat) and allow variable replacement. Variable replacement would be easy if it was simply reading in a valid JSON string and running something like FreeMarker on it, but some variable values might numeric.

Alternatively, since we're using Groovy/Grails, we could also store the menu as a Groovy config file (though I'm still not quite sure how to accomplish it with Groovy either).

I'm open to other alternatives as well if you have any ideas.

Answer

Before processing the json file you could treat it as a groovy template:

def text = '''[
    {
        "id": 1,
        "description": "Home",
    },
    {
        "id": 2,
        "description": "Receipts",
        "children": [
            {
                "id": 3,
                "description": "$receiptChild"
            }
        ]
    }
]'''

def engine = new groovy.text.SimpleTemplateEngine()
def data = [receiptChild: 'List all']
def template = engine.createTemplate text make data

def json = new groovy.json.JsonSlurper().parseText template.toString()

assert json[1].children[0].description == 'List all'

Afterwards you can read it as a json file normally.