From b47705c262de163858ca672f499aca8793834cbf Mon Sep 17 00:00:00 2001 From: Christoph Neuroth Date: Wed, 20 Mar 2013 11:35:39 +0100 Subject: [PATCH] first try at implementing the include helper this is the include helper as proposed in this pull request of the js implementation: https://github.com/wycats/handlebars.js/pull/368 the test case which accesses the parent context can't be run yet because the parser will have to be modified and I'll need some help with that once I know if this has a chance of being merged. --- .../github/jknack/handlebars/Handlebars.java | 2 + .../handlebars/helper/IncludeHelper.java | 62 +++++++++++++++++++ .../java/handlebarsjs/spec/IncludeTest.java | 39 ++++++++++++ 3 files changed, 103 insertions(+) create mode 100644 handlebars/src/main/java/com/github/jknack/handlebars/helper/IncludeHelper.java create mode 100644 handlebars/src/test/java/handlebarsjs/spec/IncludeTest.java diff --git a/handlebars/src/main/java/com/github/jknack/handlebars/Handlebars.java b/handlebars/src/main/java/com/github/jknack/handlebars/Handlebars.java index 188d63a..f5bb8dd 100644 --- a/handlebars/src/main/java/com/github/jknack/handlebars/Handlebars.java +++ b/handlebars/src/main/java/com/github/jknack/handlebars/Handlebars.java @@ -41,6 +41,7 @@ import com.github.jknack.handlebars.helper.PrecompileHelper; import com.github.jknack.handlebars.helper.UnlessHelper; import com.github.jknack.handlebars.helper.WithHelper; +import com.github.jknack.handlebars.helper.IncludeHelper; import com.github.jknack.handlebars.internal.HbsParserFactory; import com.github.jknack.handlebars.io.ClassPathTemplateLoader; @@ -815,6 +816,7 @@ private static void registerBuiltinsHelpers(final Handlebars handlebars) { handlebars.registerHelper(EmbeddedHelper.NAME, EmbeddedHelper.INSTANCE); handlebars.registerHelper(BlockHelper.NAME, BlockHelper.INSTANCE); handlebars.registerHelper(PartialHelper.NAME, PartialHelper.INSTANCE); + handlebars.registerHelper(IncludeHelper.NAME, IncludeHelper.INSTANCE); handlebars.registerHelper(PrecompileHelper.NAME, PrecompileHelper.INSTANCE); I18nHelper.registerHelpers(handlebars); diff --git a/handlebars/src/main/java/com/github/jknack/handlebars/helper/IncludeHelper.java b/handlebars/src/main/java/com/github/jknack/handlebars/helper/IncludeHelper.java new file mode 100644 index 0000000..36f1f85 --- /dev/null +++ b/handlebars/src/main/java/com/github/jknack/handlebars/helper/IncludeHelper.java @@ -0,0 +1,62 @@ +/** + * Copyright (c) 2012 Edgar Espina + * + * This file is part of Handlebars.java. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.github.jknack.handlebars.helper; + +import com.github.jknack.handlebars.Context; +import com.github.jknack.handlebars.Handlebars; +import com.github.jknack.handlebars.Helper; +import com.github.jknack.handlebars.Options; +import com.github.jknack.handlebars.Template; + +import java.io.IOException; +import java.net.URI; +import java.util.Map; + +/** + * Allows to include partials with custom context. + * This is a port of https://github.com/wycats/handlebars.js/pull/368 + */ +public class IncludeHelper implements Helper { + /** + * A singleton instance of this helper. + */ + public static final Helper INSTANCE = new IncludeHelper(); + + /** + * The helper's name. + */ + public static final String NAME = "include"; + + @Override + public CharSequence apply(final String partial, final Options options) throws IOException { + merge(options.context, options.hash); + Template template = options.handlebars.compile(URI.create(partial)); + return new Handlebars.SafeString(template.apply(options.context)); + } + + /** + * Merge everything from a hash into the given context. + * @param context the context + * @param hash the hash + */ + private void merge(final Context context, final Map hash) { + for (Map.Entry a : hash.entrySet()) { + context.data(a.getKey(), a.getValue()); + } + } +} diff --git a/handlebars/src/test/java/handlebarsjs/spec/IncludeTest.java b/handlebars/src/test/java/handlebarsjs/spec/IncludeTest.java new file mode 100644 index 0000000..79babc2 --- /dev/null +++ b/handlebars/src/test/java/handlebarsjs/spec/IncludeTest.java @@ -0,0 +1,39 @@ +package handlebarsjs.spec; + +import com.github.jknack.handlebars.AbstractTest; +import org.junit.Ignore; +import org.junit.Test; + +import java.io.IOException; + +public class IncludeTest extends AbstractTest { + + private final Hash dudes = $("dudes", + new Object[]{ + $("name", "Yehuda", "url", "http://yehuda"), + $("name", "Alan", "url", "http://alan") + }); + + @Test + public void include() throws IOException { + String template = "{{#each dudes}}{{include \"dude\" greeting=\"Hi\"}} {{/each}}"; + String partial = "{{greeting}}, {{name}}!"; + String expected = "Hi, Yehuda! Hi, Alan! "; + shouldCompileToWithPartials(template, dudes, $("dude", partial), expected); + } + + /** + * This is a port of the original test case from + * https://github.com/wycats/handlebars.js/issues/182 + */ + @Test + @Ignore("Accessing the parent context fails to parse.") + public void includeWithParentContext() throws IOException { + String template = "{{#each dudes}}{{include \"dude\" greeting=..}} {{/each}}"; + String partial = "{{greeting.hello}}, {{name}}!"; + String expected = "Hi, Yehuda! Hi, Alan! "; + Hash partials = $("dude", partial); + Hash context = $("hello", "Hi", "dudes", dudes); + shouldCompileToWithPartials(template, context, partials, expected); + } +}