采取胡子模板,传递JSON并转换为HTML

时间:2021-08-04 14:27:10

I am using this code below to merge JSON data into a template, to get HTML:

我使用下面的代码将JSON数据合并到模板中,以获取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:

我传递了一张数据图来让Mustache工作。该方法如下所示:

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:

我正在遵循胡子指南以获得Moustache自动形成。但我不知道如何得到我期待的结果。输出应如下:

<h1>Colors</h1>
<li><strong></strong></li>
<li><a href="#Green">green</a></li>
<li><a href="#Blue">blue</a></li>

2 个解决方案

#1


1  

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.

我认为您需要稍微重新考虑一下您的Mustache模板。 jMustache库(我假设您正在使用)似乎始终将{{#entities作为列表并迭代其内容,无论传入的数据类型如何。

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:

只有在提供“链接”值时才会生成HMTL锚点,从而避免了条件问题时的jMustache。所以JSON模型看起来像这样:

{
"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:

最后,您需要将JSON转换为jMustache理解的内容。我从未见过或听说过我使用的任何库中的“HTTPFunctions”类,但我过去使用过Gson做过类似的映射。请注意,这是一个非常简单的实现,您可能需要扩展它以满足您的需求:

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/

这个基本的JUnit测试演示了这个理论:http://www.pasteshare.co.uk/p/841/

#2


0  

Just use

Map<String, Object> s =  HTTPFunctions.toMap(new JSONObject(template));

#1


1  

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.

我认为您需要稍微重新考虑一下您的Mustache模板。 jMustache库(我假设您正在使用)似乎始终将{{#entities作为列表并迭代其内容,无论传入的数据类型如何。

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:

只有在提供“链接”值时才会生成HMTL锚点,从而避免了条件问题时的jMustache。所以JSON模型看起来像这样:

{
"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:

最后,您需要将JSON转换为jMustache理解的内容。我从未见过或听说过我使用的任何库中的“HTTPFunctions”类,但我过去使用过Gson做过类似的映射。请注意,这是一个非常简单的实现,您可能需要扩展它以满足您的需求:

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/

这个基本的JUnit测试演示了这个理论:http://www.pasteshare.co.uk/p/841/

#2


0  

Just use

Map<String, Object> s =  HTTPFunctions.toMap(new JSONObject(template));