2

現在、Java(com.github.jknack.handlebars)でハンドルバーを使用しており、リンクを取得するためのハンドルバーヘルパーメソッドがあります(背後にいくつかのロジックがあります)

{{ getLink data.node}}

URL /subfolder/link.html をレンダリングするだけです

私のハンドルバー テンプレートでは、ヘルパー メソッドが空でない文字列を返す場合 (たとえば、利用可能なリンクがある場合) にのみ、URL (a-tag) を出力したいと考えています。

で試してみました

{{#if getLink data.node }}
     <a href="{{ getLink data.node}}">Link-Text</a>
{{/if}}

しかし、リンクはレンダリングされませんでした

私のifの正しい構文は何ですか?

ありがとうRCX

編集: LinkHelper.class の getLink ヘルパー メソッド

public CharSequence getLink(JsonObject node, Options options) throws IOException {
    String link = fetchLink(node);
    if(link != null){
        return link;
    }
    return "";
}

経由で登録

    HandlebarsTemplateEngineImpl.getHandlebars().registerHelpers(new LinkHelper());
4

1 に答える 1

2

Handlebars.java は十分に文書化されておらず、いくつかの単体テストが欠落しています (この回答が役に立った場合は貢献することを検討してください)。何らかの理由で、このJsonObjectコミットでネストされた削除を呼び出すと、ネストされた を呼び出すことができますが、括弧にはトリックがあります。String

完全な例:

import com.github.jknack.handlebars.Context;
import com.github.jknack.handlebars.Handlebars;
import com.github.jknack.handlebars.Helper;
import com.github.jknack.handlebars.Template;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import java.io.IOException;
import java.lang.reflect.Type;
import java.util.Map;

public class HandlebarsJavaTest {

    public static void main(String[] args) throws IOException {
        Handlebars handlebars = new Handlebars();
        Gson gson = new Gson();

        handlebars.registerHelper("getLink", (Helper<Map<String, Object>>) (jsonObject, options) -> {
            String link = fetchLink(jsonObject);
            return link != null ? link : "";
        });

        String data = "{'data':{'node':'/bla.html', 'node2':'inside node2'}}";
        // Pay attention to parentheses !!!
        // {{#if (getLink data.node)}} throws ClassCastException, java.lang.String cannot be cast to java.util.Map
        String rawTemplate = "{{#if (getLink data)}} <a href=\"{{getLink data}}\">Link-Text</a> {{/if}}";

        Type type = new TypeToken<Map<String, Object>>(){}.getType();
        Map<String, Object> map = gson.fromJson(data, type);

        Template template = handlebars.compileInline(rawTemplate);
        Context context = Context.newBuilder(map).build();

        System.out.println(template.apply(context));
    }

    private static String fetchLink(Map<String, Object> map) {
        try {
            return map.get("node").toString();
        } catch (NullPointerException npe) {
            return null;
        }
    }
}

出力:

<a href="/bla.html">Link-Text</a>

ノードが単なる文字列の場合 (同じ出力)

public static void main(String[] args) throws IOException {
    Handlebars handlebars = new Handlebars();
    Gson gson = new Gson();

    handlebars.registerHelper("getLink", (Helper<String>) (node, options) -> node != null ? node : "");

    String data = "{'data':{'node':'/bla.html', 'node2':'inside node2'}}";
    // Pay attention to parentheses !!!
    String rawTemplate = "{{#if (getLink data.node)}} <a href=\"{{getLink data.node}}\">Link-Text</a> {{/if}}";

    Type type = new TypeToken<Map<String, Object>>(){}.getType();
    Map<String, Object> map = gson.fromJson(data, type);

    Template template = handlebars.compileInline(rawTemplate);
    Context context = Context.newBuilder(map).build();

    System.out.println(template.apply(context));
}

ノードが使用するオブジェクトであるthis.[data]this.[data.node]、作業を行わないことを主張する場合、同じ出力の作業例:

import com.github.jknack.handlebars.Context;
import com.github.jknack.handlebars.Handlebars;
import com.github.jknack.handlebars.Helper;
import com.google.gson.Gson;
import com.google.gson.JsonObject;

public class HandlebarsJavaTest {

    public static void main(String[] args) throws Exception {
        System.out.println(
            new Handlebars()
                .registerHelper("getLink", (Helper<JsonObject>) (json, options) -> {
                    try {
                        // logic here
                        return json.get("data").getAsJsonObject().get("node").getAsJsonObject().get("link").getAsString();
                    } catch (NullPointerException npe) {
                        return null;
                    }
                })
                // Pay attention to parentheses !!
                .compileInline("{{#if (getLink this) }} <a href=\"{{getLink this}}\">Link-Text</a> {{/if}}")
                .apply(
                    Context
                        .newBuilder(
                            new Gson()
                                .fromJson(
                                    "{ 'data': { 'node': { 'link': '/bla.html' }, 'node2': 'inside node2' } }",
                                    JsonObject.class
                                )
                        ).build()
                )
        );
    }
}

時間があれば、適切なドキュメントを追加するか、少なくとも単体テストを追加して、このオープン ソースに貢献することを検討してください{{#if (method param)}}

ソースコードによると

package com.github.jknack.handlebars;

public class IfBlockTest extends AbstractTest {

@Test
public void falsy() throws IOException {
    // empty string
    shouldCompileTo("{{#if value}}true{{else}}false{{/if}}", $("value", ""), "false");

ところで、#if組み込みのヘルパーはFalse空の文字列を返します。そのため、if 条件getLinkが実行return "";されず、テキストはレンダリングされません。これをアサートする{{else}}には、if を閉じる前に追加{{/if}}して、何がレンダリングされるかを確認します。

于 2018-03-28T14:06:57.097 に答える