From 7fe1f9397b6dd108198f2991f1c9002fe688e7e0 Mon Sep 17 00:00:00 2001 From: Timm Decker Date: Thu, 3 May 2018 11:48:12 +0200 Subject: [PATCH 1/9] Render blocks in the parent context and assure a block is passed to templates that use @partial-block --- .../jknack/handlebars/internal/Partial.java | 27 +++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/handlebars/src/main/java/com/github/jknack/handlebars/internal/Partial.java b/handlebars/src/main/java/com/github/jknack/handlebars/internal/Partial.java index 2465e1b0d..2404e3cba 100644 --- a/handlebars/src/main/java/com/github/jknack/handlebars/internal/Partial.java +++ b/handlebars/src/main/java/com/github/jknack/handlebars/internal/Partial.java @@ -23,6 +23,7 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.io.Writer; +import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.LinkedList; @@ -120,14 +121,22 @@ protected void merge(final Context context, final Writer writer) /** Inline partial? */ LinkedList> partials = context.data(Context.INLINE_PARTIALS); Map inlineTemplates = partials.getLast(); + Template callee = context.data("callee"); + + if("@partial-block".equals(path) && !isCalleeOf(callee, inlineTemplates.get("@partial-block"))) { + throw new IllegalArgumentException(callee + " does not provide a @partial-block for " + this); + } if (this.partial != null) { - this.partial.apply(context); - inlineTemplates.put("@partial-block", this.partial); + Text partialBlock = new Text(handlebars, this.partial.apply(context)); + partialBlock.filename(this.filename()); + partialBlock.position(this.position()[0], this.position()[1]); + inlineTemplates.put("@partial-block", partialBlock); } Template template = inlineTemplates.get(path); + if (template == null) { LinkedList invocationStack = context.data(Context.INVOCATION_STACK); @@ -171,8 +180,10 @@ protected void merge(final Context context, final Writer writer) } } + context.data("callee", this); Context ctx = Context.newPartialContext(context, this.scontext, hash(context)); template.apply(ctx, writer); + context.data("callee", callee); } catch (IOException ex) { String reason = String.format("The partial '%s' at '%s' could not be found", loader.resolve(path.text()), ex.getMessage()); @@ -183,6 +194,18 @@ protected void merge(final Context context, final Writer writer) } } + private boolean isCalleeOf(Template callee, Template partialBlock) { + if(callee == null || partialBlock == null) { + return false; + } + + if(!callee.filename().equalsIgnoreCase(partialBlock.filename())) { + return false; + } + + return Arrays.equals(callee.position(), partialBlock.position()); + } + /** * True, if the file was already processed. * From 0b057c301d14aafbfac02a28db7ee33b2caad5a2 Mon Sep 17 00:00:00 2001 From: Timm Decker Date: Thu, 3 May 2018 13:53:58 +0200 Subject: [PATCH 2/9] Fixed checkstyle errors. --- .../jknack/handlebars/internal/Partial.java | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/handlebars/src/main/java/com/github/jknack/handlebars/internal/Partial.java b/handlebars/src/main/java/com/github/jknack/handlebars/internal/Partial.java index 2404e3cba..4e2b7726a 100644 --- a/handlebars/src/main/java/com/github/jknack/handlebars/internal/Partial.java +++ b/handlebars/src/main/java/com/github/jknack/handlebars/internal/Partial.java @@ -123,8 +123,14 @@ protected void merge(final Context context, final Writer writer) Map inlineTemplates = partials.getLast(); Template callee = context.data("callee"); - if("@partial-block".equals(path) && !isCalleeOf(callee, inlineTemplates.get("@partial-block"))) { - throw new IllegalArgumentException(callee + " does not provide a @partial-block for " + this); + final boolean pathIsPartialBlock = "@partial-block".equals(path); + final Template lastPartialBlock = inlineTemplates.get("@partial-block"); + final boolean parentIsNotLastPartialBlock = !isCalleeOf(callee, lastPartialBlock); + + if (pathIsPartialBlock && parentIsNotLastPartialBlock) { + throw new IllegalArgumentException( + callee + " does not provide a @partial-block for " + this + ); } if (this.partial != null) { @@ -194,12 +200,17 @@ protected void merge(final Context context, final Writer writer) } } - private boolean isCalleeOf(Template callee, Template partialBlock) { - if(callee == null || partialBlock == null) { + /** + * @param callee parent template of the currently traversed template + * @param partialBlock partial block candidate + * @return returns if callee and partialBlock are the same + */ + private boolean isCalleeOf(final Template callee, final Template partialBlock) { + if (callee == null || partialBlock == null) { return false; } - if(!callee.filename().equalsIgnoreCase(partialBlock.filename())) { + if (!callee.filename().equalsIgnoreCase(partialBlock.filename())) { return false; } From e41b907fab621c2c6db50b28a02602584236cb66 Mon Sep 17 00:00:00 2001 From: Timm Decker Date: Thu, 3 May 2018 16:44:51 +0200 Subject: [PATCH 3/9] Readded lazy evaluation. --- .../jknack/handlebars/internal/Partial.java | 38 +++++---- .../PartialBlockForwardingTemplate.java | 80 +++++++++++++++++++ 2 files changed, 102 insertions(+), 16 deletions(-) create mode 100644 handlebars/src/main/java/com/github/jknack/handlebars/internal/PartialBlockForwardingTemplate.java diff --git a/handlebars/src/main/java/com/github/jknack/handlebars/internal/Partial.java b/handlebars/src/main/java/com/github/jknack/handlebars/internal/Partial.java index 4e2b7726a..f32b6724c 100644 --- a/handlebars/src/main/java/com/github/jknack/handlebars/internal/Partial.java +++ b/handlebars/src/main/java/com/github/jknack/handlebars/internal/Partial.java @@ -92,7 +92,7 @@ class Partial extends HelperResolver { * @param hash Template params */ public Partial(final Handlebars handlebars, final Template path, final String context, - final Map hash) { + final Map hash) { super(handlebars); this.path = notNull(path, "The path is required."); this.context = context; @@ -115,7 +115,7 @@ public void after(final Context context, final Writer writer) throws IOException @Override protected void merge(final Context context, final Writer writer) - throws IOException { + throws IOException { try { String path = this.path.apply(context); /** Inline partial? */ @@ -134,10 +134,14 @@ protected void merge(final Context context, final Writer writer) } if (this.partial != null) { - Text partialBlock = new Text(handlebars, this.partial.apply(context)); - partialBlock.filename(this.filename()); - partialBlock.position(this.position()[0], this.position()[1]); - inlineTemplates.put("@partial-block", partialBlock); + inlineTemplates.put("@partial-block", + new PartialBlockForwardingTemplate(this, + this.partial, + inlineTemplates.get("@partial-block"), + callee, + handlebars + ) + ); } Template template = inlineTemplates.get(path); @@ -157,18 +161,20 @@ protected void merge(final Context context, final Writer writer) final String reason; if (invocationStack.isEmpty()) { reason = String.format("infinite loop detected, partial '%s' is calling itself", - source.filename()); + source.filename()); message = String.format("%s:%s:%s: %s", caller.filename(), line, column, reason); } else { reason = String.format( - "infinite loop detected, partial '%s' was previously loaded", source.filename()); + "infinite loop detected, partial '%s' was previously loaded", + source.filename() + ); message = String.format("%s:%s:%s: %s\n%s", caller.filename(), line, column, reason, - "at " + join(invocationStack, "\nat ")); + "at " + join(invocationStack, "\nat ")); } HandlebarsError error = new HandlebarsError(caller.filename(), line, - column, reason, text(), message); + column, reason, text(), message); throw new HandlebarsException(error); } @@ -192,10 +198,10 @@ protected void merge(final Context context, final Writer writer) context.data("callee", callee); } catch (IOException ex) { String reason = String.format("The partial '%s' at '%s' could not be found", - loader.resolve(path.text()), ex.getMessage()); + loader.resolve(path.text()), ex.getMessage()); String message = String.format("%s:%s:%s: %s", filename, line, column, reason); HandlebarsError error = new HandlebarsError(filename, line, - column, reason, text(), message); + column, reason, text(), message); throw new HandlebarsException(error); } } @@ -225,7 +231,7 @@ private boolean isCalleeOf(final Template callee, final Template partialBlock) { * @return True, if the file was already processed. */ private static boolean exists(final List invocationStack, - final String filename) { + final String filename) { for (TemplateSource ts : invocationStack) { if (ts.filename().equals(filename)) { return true; @@ -302,8 +308,8 @@ private String partialInput(final String input, final String indent) { public String text() { String path = this.path.text(); StringBuilder buffer = new StringBuilder(startDelimiter) - .append('>') - .append(path); + .append('>') + .append(path); if (context != null) { buffer.append(' ').append(context); @@ -313,7 +319,7 @@ public String text() { if (this.partial != null) { buffer.append(this.partial.text()).append(startDelimiter, 0, startDelimiter.length() - 1) - .append("/").append(path).append(endDelimiter); + .append("/").append(path).append(endDelimiter); } return buffer.toString(); } diff --git a/handlebars/src/main/java/com/github/jknack/handlebars/internal/PartialBlockForwardingTemplate.java b/handlebars/src/main/java/com/github/jknack/handlebars/internal/PartialBlockForwardingTemplate.java new file mode 100644 index 000000000..dab861fc8 --- /dev/null +++ b/handlebars/src/main/java/com/github/jknack/handlebars/internal/PartialBlockForwardingTemplate.java @@ -0,0 +1,80 @@ +package com.github.jknack.handlebars.internal; + +import com.github.jknack.handlebars.Context; +import com.github.jknack.handlebars.Handlebars; +import com.github.jknack.handlebars.Template; + +import java.io.IOException; +import java.io.Writer; +import java.util.LinkedList; +import java.util.Map; + +/** + * + */ +public class PartialBlockForwardingTemplate extends BaseTemplate { + /** + * The block to be passed as partial-block. + */ + private final Template block; + + /** + * The previous partial-block definition of the template which contains this partial. + */ + private final Template parentPartialBlock; + + /** + * The callee of the parent partial. + */ + private final Template callee; + + /** + * Constructs a PartialBlockForwardingTemplate. + * + * @param parent the parent partial + * @param block the block to be passed as partial-block. + * @param parentPartialBlock the previous partial-block definition of + * the template which contains this partial. + * @param callee the template that renders the parent + * @param handlebars handlebars + */ + public PartialBlockForwardingTemplate( + final Template parent, + final Template block, + final Template parentPartialBlock, + final Template callee, + final Handlebars handlebars + ) { + super(handlebars); + this.block = block; + this.parentPartialBlock = parentPartialBlock; + this.callee = callee; + this.filename(block.filename()); + this.position(parent.position()[0], parent.position()[1]); + } + + /** + * {@inheritDoc} + */ + @Override + protected void merge(final Context context, final Writer writer) throws IOException { + LinkedList> partials = context.data(Context.INLINE_PARTIALS); + Map inlineTemplates = partials.getLast(); + Template oldPartialBlock = inlineTemplates.get("@partial-block"); + Template oldCallee = context.data("callee"); + + context.data("callee", callee); + inlineTemplates.put("@partial-block", parentPartialBlock); + block.apply(context, writer); + inlineTemplates.put("@partial-block", oldPartialBlock); + context.data("callee", oldCallee); + } + + /** + * {@inheritDoc} + */ + @Override + public String text() { + return block.text(); + } +} From 91da4d32e0f891df859da01bb31b4f58105351b5 Mon Sep 17 00:00:00 2001 From: Timm Decker Date: Fri, 4 May 2018 14:33:31 +0200 Subject: [PATCH 4/9] Readded inline partial evaluation. --- .../jknack/handlebars/internal/Partial.java | 5 +++-- .../PartialBlockForwardingTemplate.java | 17 +++++++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/handlebars/src/main/java/com/github/jknack/handlebars/internal/Partial.java b/handlebars/src/main/java/com/github/jknack/handlebars/internal/Partial.java index f32b6724c..ad1f04a63 100644 --- a/handlebars/src/main/java/com/github/jknack/handlebars/internal/Partial.java +++ b/handlebars/src/main/java/com/github/jknack/handlebars/internal/Partial.java @@ -134,14 +134,15 @@ protected void merge(final Context context, final Writer writer) } if (this.partial != null) { - inlineTemplates.put("@partial-block", + this.partial.apply(context); + inlineTemplates.put("@partial-block", new PartialBlockForwardingTemplate(this, this.partial, inlineTemplates.get("@partial-block"), callee, handlebars ) - ); + ); } Template template = inlineTemplates.get(path); diff --git a/handlebars/src/main/java/com/github/jknack/handlebars/internal/PartialBlockForwardingTemplate.java b/handlebars/src/main/java/com/github/jknack/handlebars/internal/PartialBlockForwardingTemplate.java index dab861fc8..69a8d22a1 100644 --- a/handlebars/src/main/java/com/github/jknack/handlebars/internal/PartialBlockForwardingTemplate.java +++ b/handlebars/src/main/java/com/github/jknack/handlebars/internal/PartialBlockForwardingTemplate.java @@ -1,3 +1,20 @@ +/** + * Copyright (c) 2012-2015 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.internal; import com.github.jknack.handlebars.Context; From cff998b470a3009b1fd0deb91af4f59c32e06d97 Mon Sep 17 00:00:00 2001 From: Timm Decker Date: Mon, 7 May 2018 13:34:41 +0200 Subject: [PATCH 5/9] Added option to turn lazy partial evaluation on and off --- .../github/jknack/handlebars/Handlebars.java | 37 +++++++++++++++++++ .../jknack/handlebars/internal/Partial.java | 19 ++++++---- .../jknack/handlebars/PartialBlockTest.java | 5 +++ 3 files changed, 53 insertions(+), 8 deletions(-) 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 d08642cae..37c65cfd1 100644 --- a/handlebars/src/main/java/com/github/jknack/handlebars/Handlebars.java +++ b/handlebars/src/main/java/com/github/jknack/handlebars/Handlebars.java @@ -261,6 +261,12 @@ public static CharSequence escapeExpression(final CharSequence input) { */ private boolean prettyPrint; + /** + * If true, given partial blocks are not evaluated when defined but when used. + * If false, partial blocks are evaluated when defined and used. + */ + private boolean lazyPartialBlockEvaluation; + /** * The helper registry. */ @@ -740,6 +746,37 @@ public boolean stringParams() { return stringParams; } + + /** + * If true, given partial blocks are not evaluated when defined but when used. + * If false, partial blocks are evaluated when defined and used. + * @return If true, given partial blocks are not evaluated when defined but when used. + * If false, partial blocks are evaluated when defined and used. + */ + public boolean lazyPartialBlockEvaluation() { + return lazyPartialBlockEvaluation; + } + + + /** + * If true, given partial blocks are not evaluated when defined but when used. + * If false, partial blocks are evaluated when defined and used. + */ + public void setLazyPartialBlockEvaluation(final boolean lazyPartialBlockEvaluation) { + this.lazyPartialBlockEvaluation = lazyPartialBlockEvaluation; + } + + /** + * If true, given partial blocks are not evaluated when defined but when used. + * If false, partial blocks are evaluated when defined and used. + * @return The handlebars object. + */ + public Handlebars lazyPartialBlockEvaluation(final boolean lazyPartialBlockEvaluation) { + setLazyPartialBlockEvaluation(lazyPartialBlockEvaluation); + return this; + } + + /** * If true, unnecessary spaces and new lines will be removed from output. Default is: false. * diff --git a/handlebars/src/main/java/com/github/jknack/handlebars/internal/Partial.java b/handlebars/src/main/java/com/github/jknack/handlebars/internal/Partial.java index ad1f04a63..c9a1dc1bc 100644 --- a/handlebars/src/main/java/com/github/jknack/handlebars/internal/Partial.java +++ b/handlebars/src/main/java/com/github/jknack/handlebars/internal/Partial.java @@ -134,15 +134,18 @@ protected void merge(final Context context, final Writer writer) } if (this.partial != null) { + if (!handlebars.lazyPartialBlockEvaluation()) { this.partial.apply(context); - inlineTemplates.put("@partial-block", - new PartialBlockForwardingTemplate(this, - this.partial, - inlineTemplates.get("@partial-block"), - callee, - handlebars - ) - ); + } + + inlineTemplates.put("@partial-block", + new PartialBlockForwardingTemplate(this, + this.partial, + inlineTemplates.get("@partial-block"), + callee, + handlebars + ) + ); } Template template = inlineTemplates.get(path); diff --git a/handlebars/src/test/java/com/github/jknack/handlebars/PartialBlockTest.java b/handlebars/src/test/java/com/github/jknack/handlebars/PartialBlockTest.java index 784dace34..19da6b77b 100644 --- a/handlebars/src/test/java/com/github/jknack/handlebars/PartialBlockTest.java +++ b/handlebars/src/test/java/com/github/jknack/handlebars/PartialBlockTest.java @@ -8,6 +8,11 @@ public class PartialBlockTest extends AbstractTest { + @Override + protected Handlebars newHandlebars() { + return super.newHandlebars().lazyPartialBlockEvaluation(false); + } + @Test public void text() throws IOException { assertEquals("{{#>dude}}{{#*inline \"myPartial\"}}success{{/inline}}{{/dude}}", From 50e7eb843083dff8e5f8dd5d95ab8e3b092bd401 Mon Sep 17 00:00:00 2001 From: Timm Decker Date: Mon, 7 May 2018 13:40:03 +0200 Subject: [PATCH 6/9] Fix checkstyle errors. --- .../src/main/java/com/github/jknack/handlebars/Handlebars.java | 2 ++ 1 file changed, 2 insertions(+) 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 37c65cfd1..d897a7c36 100644 --- a/handlebars/src/main/java/com/github/jknack/handlebars/Handlebars.java +++ b/handlebars/src/main/java/com/github/jknack/handlebars/Handlebars.java @@ -761,6 +761,7 @@ public boolean lazyPartialBlockEvaluation() { /** * If true, given partial blocks are not evaluated when defined but when used. * If false, partial blocks are evaluated when defined and used. + * @param lazyPartialBlockEvaluation Flag to turn it off and on */ public void setLazyPartialBlockEvaluation(final boolean lazyPartialBlockEvaluation) { this.lazyPartialBlockEvaluation = lazyPartialBlockEvaluation; @@ -769,6 +770,7 @@ public void setLazyPartialBlockEvaluation(final boolean lazyPartialBlockEvaluati /** * If true, given partial blocks are not evaluated when defined but when used. * If false, partial blocks are evaluated when defined and used. + * @param lazyPartialBlockEvaluation Flag to turn it off and on * @return The handlebars object. */ public Handlebars lazyPartialBlockEvaluation(final boolean lazyPartialBlockEvaluation) { From 0155376c2bf985ef649cbead44989c85b44052eb Mon Sep 17 00:00:00 2001 From: Timm Decker Date: Thu, 17 May 2018 15:29:25 +0200 Subject: [PATCH 7/9] Revert to original whitespaces --- .../com/github/jknack/handlebars/Context.java | 5 ++++ .../jknack/handlebars/internal/Partial.java | 29 +++++++++---------- .../PartialBlockForwardingTemplate.java | 6 ++-- 3 files changed, 21 insertions(+), 19 deletions(-) diff --git a/handlebars/src/main/java/com/github/jknack/handlebars/Context.java b/handlebars/src/main/java/com/github/jknack/handlebars/Context.java index 4e4cd9ca7..9aeb26d8f 100644 --- a/handlebars/src/main/java/com/github/jknack/handlebars/Context.java +++ b/handlebars/src/main/java/com/github/jknack/handlebars/Context.java @@ -402,6 +402,11 @@ public Object eval(final ValueResolver resolver, final Context context, final Ob */ public static final String PARAM_SIZE = Context.class.getName() + "#paramSize"; + /** + * Last callee of a partial block. Internal use. + */ + public static final String CALLEE = Context.class.getName() + "#callee"; + /** * The parent context. Optional. */ diff --git a/handlebars/src/main/java/com/github/jknack/handlebars/internal/Partial.java b/handlebars/src/main/java/com/github/jknack/handlebars/internal/Partial.java index c9a1dc1bc..cf580a135 100644 --- a/handlebars/src/main/java/com/github/jknack/handlebars/internal/Partial.java +++ b/handlebars/src/main/java/com/github/jknack/handlebars/internal/Partial.java @@ -92,7 +92,7 @@ class Partial extends HelperResolver { * @param hash Template params */ public Partial(final Handlebars handlebars, final Template path, final String context, - final Map hash) { + final Map hash) { super(handlebars); this.path = notNull(path, "The path is required."); this.context = context; @@ -115,13 +115,13 @@ public void after(final Context context, final Writer writer) throws IOException @Override protected void merge(final Context context, final Writer writer) - throws IOException { + throws IOException { try { String path = this.path.apply(context); /** Inline partial? */ LinkedList> partials = context.data(Context.INLINE_PARTIALS); Map inlineTemplates = partials.getLast(); - Template callee = context.data("callee"); + Template callee = context.data(Context.CALLEE); final boolean pathIsPartialBlock = "@partial-block".equals(path); final Template lastPartialBlock = inlineTemplates.get("@partial-block"); @@ -150,7 +150,6 @@ protected void merge(final Context context, final Writer writer) Template template = inlineTemplates.get(path); - if (template == null) { LinkedList invocationStack = context.data(Context.INVOCATION_STACK); @@ -165,20 +164,18 @@ protected void merge(final Context context, final Writer writer) final String reason; if (invocationStack.isEmpty()) { reason = String.format("infinite loop detected, partial '%s' is calling itself", - source.filename()); + source.filename()); message = String.format("%s:%s:%s: %s", caller.filename(), line, column, reason); } else { reason = String.format( - "infinite loop detected, partial '%s' was previously loaded", - source.filename() - ); + "infinite loop detected, partial '%s' was previously loaded", source.filename()); message = String.format("%s:%s:%s: %s\n%s", caller.filename(), line, column, reason, - "at " + join(invocationStack, "\nat ")); + "at " + join(invocationStack, "\nat ")); } HandlebarsError error = new HandlebarsError(caller.filename(), line, - column, reason, text(), message); + column, reason, text(), message); throw new HandlebarsException(error); } @@ -196,10 +193,10 @@ protected void merge(final Context context, final Writer writer) } } - context.data("callee", this); + context.data(Context.CALLEE, this); Context ctx = Context.newPartialContext(context, this.scontext, hash(context)); template.apply(ctx, writer); - context.data("callee", callee); + context.data(Context.CALLEE, callee); } catch (IOException ex) { String reason = String.format("The partial '%s' at '%s' could not be found", loader.resolve(path.text()), ex.getMessage()); @@ -235,7 +232,7 @@ private boolean isCalleeOf(final Template callee, final Template partialBlock) { * @return True, if the file was already processed. */ private static boolean exists(final List invocationStack, - final String filename) { + final String filename) { for (TemplateSource ts : invocationStack) { if (ts.filename().equals(filename)) { return true; @@ -312,8 +309,8 @@ private String partialInput(final String input, final String indent) { public String text() { String path = this.path.text(); StringBuilder buffer = new StringBuilder(startDelimiter) - .append('>') - .append(path); + .append('>') + .append(path); if (context != null) { buffer.append(' ').append(context); @@ -323,7 +320,7 @@ public String text() { if (this.partial != null) { buffer.append(this.partial.text()).append(startDelimiter, 0, startDelimiter.length() - 1) - .append("/").append(path).append(endDelimiter); + .append("/").append(path).append(endDelimiter); } return buffer.toString(); } diff --git a/handlebars/src/main/java/com/github/jknack/handlebars/internal/PartialBlockForwardingTemplate.java b/handlebars/src/main/java/com/github/jknack/handlebars/internal/PartialBlockForwardingTemplate.java index 69a8d22a1..c4e8a9f07 100644 --- a/handlebars/src/main/java/com/github/jknack/handlebars/internal/PartialBlockForwardingTemplate.java +++ b/handlebars/src/main/java/com/github/jknack/handlebars/internal/PartialBlockForwardingTemplate.java @@ -78,13 +78,13 @@ protected void merge(final Context context, final Writer writer) throws IOExcept LinkedList> partials = context.data(Context.INLINE_PARTIALS); Map inlineTemplates = partials.getLast(); Template oldPartialBlock = inlineTemplates.get("@partial-block"); - Template oldCallee = context.data("callee"); + Template oldCallee = context.data(Context.CALLEE); - context.data("callee", callee); + context.data(Context.CALLEE, callee); inlineTemplates.put("@partial-block", parentPartialBlock); block.apply(context, writer); inlineTemplates.put("@partial-block", oldPartialBlock); - context.data("callee", oldCallee); + context.data(Context.CALLEE, oldCallee); } /** From 90d11bfe92238680eae2687ebbb8e1dace1e063e Mon Sep 17 00:00:00 2001 From: Timm Decker Date: Thu, 17 May 2018 15:31:04 +0200 Subject: [PATCH 8/9] Revert to original whitespace --- .../java/com/github/jknack/handlebars/internal/Partial.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/handlebars/src/main/java/com/github/jknack/handlebars/internal/Partial.java b/handlebars/src/main/java/com/github/jknack/handlebars/internal/Partial.java index cf580a135..bbc860ea0 100644 --- a/handlebars/src/main/java/com/github/jknack/handlebars/internal/Partial.java +++ b/handlebars/src/main/java/com/github/jknack/handlebars/internal/Partial.java @@ -199,10 +199,10 @@ protected void merge(final Context context, final Writer writer) context.data(Context.CALLEE, callee); } catch (IOException ex) { String reason = String.format("The partial '%s' at '%s' could not be found", - loader.resolve(path.text()), ex.getMessage()); + loader.resolve(path.text()), ex.getMessage()); String message = String.format("%s:%s:%s: %s", filename, line, column, reason); HandlebarsError error = new HandlebarsError(filename, line, - column, reason, text(), message); + column, reason, text(), message); throw new HandlebarsException(error); } } From 94f37c07fe9d6d0d2111226686fb0de8eefcc4d7 Mon Sep 17 00:00:00 2001 From: Timm Decker Date: Fri, 18 May 2018 09:20:26 +0200 Subject: [PATCH 9/9] Added tests for lazy partial block evaluation --- .../LazyPartialBlockEvaluationTest.java | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 handlebars/src/test/java/com/github/jknack/handlebars/LazyPartialBlockEvaluationTest.java diff --git a/handlebars/src/test/java/com/github/jknack/handlebars/LazyPartialBlockEvaluationTest.java b/handlebars/src/test/java/com/github/jknack/handlebars/LazyPartialBlockEvaluationTest.java new file mode 100644 index 000000000..3cacee005 --- /dev/null +++ b/handlebars/src/test/java/com/github/jknack/handlebars/LazyPartialBlockEvaluationTest.java @@ -0,0 +1,32 @@ +package com.github.jknack.handlebars; + +import org.junit.Test; + +import java.io.IOException; + +import static junit.framework.TestCase.assertEquals; + +public class LazyPartialBlockEvaluationTest extends AbstractTest { + @Override + protected void configure(Handlebars handlebars) { + handlebars.setLazyPartialBlockEvaluation(true); + } + + @Test + public void shouldSupportMultipleLevelsOfNestedPartialBlocks() throws IOException { + String myMoreNestedPartial = "I{{> @partial-block}}I"; + String myNestedPartial = "A{{#> myMoreNestedPartial}}{{> @partial-block}}{{/myMoreNestedPartial}}B"; + String myPartial = "{{#> myNestedPartial}}{{> @partial-block}}{{/myNestedPartial}}"; + Template t = compile("C{{#> myPartial}}hello{{/myPartial}}D", new Hash(), $("myPartial", myPartial, "myNestedPartial", myNestedPartial,"myMoreNestedPartial", myMoreNestedPartial)); + String result = t.apply(null); + assertEquals("'CAIhelloIBD' should === '" + result + "': ", "CAIhelloIBD", result); + } + + @Test(expected = HandlebarsException.class) + public void shouldNotDefineInlinePartialsInPartialBlockCall() throws IOException { + // myPartial should not be defined and thus throw a handlebars exception + shouldCompileToWithPartials( + "{{#> dude}}{{#*inline \"myPartial\"}}success{{/inline}}{{/dude}}", + $, $("dude", "{{> myPartial }}"), ""); + } +}