From 867ccf84b896ac125c95b6ef6aa346b4b9df8976 Mon Sep 17 00:00:00 2001 From: Martin Kouba Date: Thu, 22 Jul 2021 13:53:05 +0200 Subject: [PATCH] Qute - register param expressions for includes and user-defined tags - only registered expression can be validated at build time --- .../io/quarkus/qute/IncludeSectionHelper.java | 16 +++++++++++++++- .../io/quarkus/qute/UserTagSectionHelper.java | 17 ++++++++++++++++- .../java/io/quarkus/qute/IncludeTest.java | 5 ++++- .../java/io/quarkus/qute/UserTagTest.java | 19 +++++++++++++++++++ 4 files changed, 54 insertions(+), 3 deletions(-) diff --git a/independent-projects/qute/core/src/main/java/io/quarkus/qute/IncludeSectionHelper.java b/independent-projects/qute/core/src/main/java/io/quarkus/qute/IncludeSectionHelper.java index b3a0b59497313..11841e15e3a53 100644 --- a/independent-projects/qute/core/src/main/java/io/quarkus/qute/IncludeSectionHelper.java +++ b/independent-projects/qute/core/src/main/java/io/quarkus/qute/IncludeSectionHelper.java @@ -77,6 +77,20 @@ public boolean treatUnknownSectionsAsBlocks() { return true; } + @Override + public Scope initializeBlock(Scope outerScope, BlockInfo block) { + if (block.getLabel().equals(MAIN_BLOCK_NAME)) { + for (Entry entry : block.getParameters().entrySet()) { + if (!entry.getKey().equals(TEMPLATE)) { + block.addExpression(entry.getKey(), entry.getValue()); + } + } + return outerScope; + } else { + return outerScope; + } + } + @Override public IncludeSectionHelper initialize(SectionInitContext context) { @@ -97,7 +111,7 @@ public IncludeSectionHelper initialize(SectionInitContext context) { params = new HashMap<>(); for (Entry entry : context.getParameters().entrySet()) { if (!entry.getKey().equals(TEMPLATE)) { - params.put(entry.getKey(), context.parseValue(entry.getValue())); + params.put(entry.getKey(), context.getExpression(entry.getKey())); } } } diff --git a/independent-projects/qute/core/src/main/java/io/quarkus/qute/UserTagSectionHelper.java b/independent-projects/qute/core/src/main/java/io/quarkus/qute/UserTagSectionHelper.java index 6a53eed114832..7e6b4cfb36012 100644 --- a/independent-projects/qute/core/src/main/java/io/quarkus/qute/UserTagSectionHelper.java +++ b/independent-projects/qute/core/src/main/java/io/quarkus/qute/UserTagSectionHelper.java @@ -82,6 +82,21 @@ public ParametersInfo getParameters() { return ParametersInfo.builder().addParameter(new Parameter(IT, IT, false)).build(); } + @Override + public Scope initializeBlock(Scope outerScope, BlockInfo block) { + if (block.getLabel().equals(MAIN_BLOCK_NAME)) { + for (Entry entry : block.getParameters().entrySet()) { + if (entry.getKey().equals(IT) && entry.getValue().equals(IT)) { + continue; + } + block.addExpression(entry.getKey(), entry.getValue()); + } + return outerScope; + } else { + return outerScope; + } + } + @Override public UserTagSectionHelper initialize(SectionInitContext context) { Map params = new HashMap<>(); @@ -89,7 +104,7 @@ public UserTagSectionHelper initialize(SectionInitContext context) { if (entry.getKey().equals(IT) && entry.getValue().equals(IT)) { continue; } - params.put(entry.getKey(), context.parseValue(entry.getValue())); + params.put(entry.getKey(), context.getExpression(entry.getKey())); } boolean isEmpty = context.getBlocks().size() == 1 && context.getBlocks().get(0).isEmpty(); final Engine engine = context.getEngine(); diff --git a/independent-projects/qute/core/src/test/java/io/quarkus/qute/IncludeTest.java b/independent-projects/qute/core/src/test/java/io/quarkus/qute/IncludeTest.java index 5cc4ee749f539..cc4ff4e4f048d 100644 --- a/independent-projects/qute/core/src/test/java/io/quarkus/qute/IncludeTest.java +++ b/independent-projects/qute/core/src/test/java/io/quarkus/qute/IncludeTest.java @@ -114,7 +114,10 @@ public void testEmptyInclude() { public void testInsertParam() { Engine engine = Engine.builder().addDefaults().build(); engine.putTemplate("super", engine.parse("{#insert header}default header{/insert} and {#insert footer}{that}{/}")); - assertEquals("1 and 1", engine.parse("{#include 'super' that=foo}{#header}{that}{/}{/}").data("foo", 1).render()); + Template foo = engine.parse("{#include 'super' that=foo}{#header}{that}{/}{/}"); + // foo, that + assertEquals(2, foo.getExpressions().size()); + assertEquals("1 and 1", foo.data("foo", 1).render()); } @Test diff --git a/independent-projects/qute/core/src/test/java/io/quarkus/qute/UserTagTest.java b/independent-projects/qute/core/src/test/java/io/quarkus/qute/UserTagTest.java index baea6c031fb36..cb29a4e368a23 100644 --- a/independent-projects/qute/core/src/test/java/io/quarkus/qute/UserTagTest.java +++ b/independent-projects/qute/core/src/test/java/io/quarkus/qute/UserTagTest.java @@ -16,6 +16,8 @@ public void testUserTag() { .build(); Template tag = engine.parse("{#if showImage.or(false)}{it.name}{#else}nope{/if}"); + // showImage.or(false), it.name + assertEquals(2, tag.getExpressions().size()); engine.putTemplate("my-tag-id", tag); Map order = new HashMap<>(); @@ -72,7 +74,24 @@ public void testUserTagWithRichNestedContent() { assertEquals("Herbert", engine.parse("{#myTag showImage=true}{#myTag2 showImage2=true}{order.name}{/myTag2}{/myTag}") .render(Collections.singletonMap("order", order))); + } + + @Test + public void testUserTagLoopParam() { + Engine engine = Engine.builder().addDefaults().addValueResolver(new ReflectionValueResolver()) + .addSectionHelper(new UserTagSectionHelper.Factory("myTag", "my-tag-id")) + .build(); + + Template tag = engine.parse("{it} {surname}"); + engine.putTemplate("my-tag-id", tag); + assertEquals("KOUBA kouba", + engine.parse("{#each surnames}{#myTag it.toUpperCase surname=it.toLowerCase /}{/each}") + .data("surnames", Collections.singleton("Kouba")).render()); + assertEquals("KOUBA kouba", + engine.parse( + "{#for surname in surnames}{#each surnames}{#myTag it.toUpperCase surname=surname.toLowerCase /}{/each}{/for}") + .data("surnames", Collections.singleton("Kouba")).render()); } }