I am using this code below to merge JSON data into a template, to get HTML:
Template:
String schema = "<h1>{{header}}</h1>"
+ "{{#bug}}{{/bug}}"
+ "{{#items}}"
+ "{{#first}}"
+ "<li><strong>{{title}}</strong>
+ </li>"
+ "{{/first}}"
+ "{{#link}}"
+ "<li><a href=\"{{url}}\">{{name}}
+ </a></li>"
+ "{{/link}}"
+ "{{/items}}"
+ "{{#empty}}"
+ "<p>The list is empty.</p>"
+ "{{/empty}}";
JSON object:
try {
String template = "{\"header\": \"Colors\", "
+ "\"items\": [ "
+ "{\"name\": \"red\", \"first\": true, \"url\": \"#Red\"}, "
+ "{\"name\": \"green\", \"link\": true, \"url\": \"#Green\"}, "
+ "{\"name\": \"blue\", \"link\": true, \"url\": \"#Blue\"}"
+ " ], \"empty\": false }";
JSONObject jsonWithArrayInIt = new JSONObject(template);
JSONArray items = jsonWithArrayInIt.getJSONArray("items");
Map<String,String> ctx = new HashMap<String,String>();
ctx.put("foo.bar", "baz");
Mustache.compiler().standardsMode(true).compile("{{foo.bar}}").execute(ctx);
System.out.println("itemised: " + items.toString());
} catch(JSONException je) {
//Error while creating JSON.
}
I pass a map of data to get Mustache to work. The method looks like this:
public static Map<String, Object> toMap(JSONObject object)
throws JSONException {
Map<String, Object> map = new HashMap();
Iterator keys = object.keys();
while (keys.hasNext()) {
String key = (String) keys.next();
map.put(key, fromJson(object.get(key)));
}
return map;
}
I am following a Mustache Guide to get the Mustache autoformation. But I don't know how to get the result I am expecting. The output should be as follows:
<h1>Colors</h1>
<li><strong></strong></li>
<li><a href="#Green">green</a></li>
<li><a href="#Blue">blue</a></li>
I think you need to rethink your Mustache template slightly. The jMustache library (which I assume you are using) seems to always treat {{#
entities as lists and iterate their contents, regardless of the data type passed in.
Something like this should work:
<h1>{{header}}</h1>
{{#items}}
<li>
{{#url}}<a href="{{.}}">{{/url}}
{{^url}}<strong>{{/url}}
{{caption}}
{{#url}}</a>{{/url}}
{{^url}}</strong>{{/url}}
</li>
{{/items}}
{{^items}}
<p>The list is empty.</p>
{{/items}}
This will produce an HMTL anchor only if a "link" value is provided, thus avoiding the jMustache if condition issue. So the JSON model would look something like this:
{
"header": "Colors",
"items": [
{"caption": "title"},
{"caption": "red", "url": "#Red"},
{"caption": "green", "url": "#Green"},
{"caption": "blue", "url": "#Blue"}
]
}
Finally, you will need to convert your JSON to something jMustache understands. I've never seen or heard of the "HTTPFunctions" class in any library I've used, but I've done some similar mapping using Gson in the past. Note that this is a very simple implementation and you may need to extend it to fit your needs:
private Map<String, Object> getModelFromJson(JSONObject json) throws JSONException {
Map<String,Object> out = new HashMap<String,Object>();
Iterator it = json.keys();
while (it.hasNext()) {
String key = (String)it.next();
if (json.get(key) instanceof JSONArray) {
// Copy an array
JSONArray arrayIn = json.getJSONArray(key);
List<Object> arrayOut = new ArrayList<Object>();
for (int i = 0; i < arrayIn.length(); i++) {
JSONObject item = (JSONObject)arrayIn.get(i);
Map<String, Object> items = getModelFromJson(item);
arrayOut.add(items);
}
out.put(key, arrayOut);
}
else {
// Copy a primitive string
out.put(key, json.getString(key));
}
}
return out;
}
This basic JUnit test demonstrates the theory: http://www.pasteshare.co.uk/p/841/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With