From df395da792fac8318ee0fc17c033617ce828dd5a Mon Sep 17 00:00:00 2001 From: Jesse Brault Date: Sun, 1 Jun 2025 11:53:30 -0500 Subject: [PATCH] Update Render component to accept multiple items, closures, and default to rendering it to a component writer. --- .../view/component/web/lib/Render.groovy | 28 ++++++++++++------- .../view/component/web/lib/OutletTests.groovy | 1 - .../view/component/web/lib/RenderTests.groovy | 24 ++++++++++++++++ 3 files changed, 42 insertions(+), 11 deletions(-) diff --git a/web-view-components/src/main/groovy/groowt/view/component/web/lib/Render.groovy b/web-view-components/src/main/groovy/groowt/view/component/web/lib/Render.groovy index a4072c2..b0981df 100644 --- a/web-view-components/src/main/groovy/groowt/view/component/web/lib/Render.groovy +++ b/web-view-components/src/main/groovy/groowt/view/component/web/lib/Render.groovy @@ -1,26 +1,34 @@ package groowt.view.component.web.lib import groowt.view.View +import groowt.view.component.runtime.DefaultComponentWriter class Render extends DelegatingWebViewComponent { - private final Object item + private final Object items Render(Map attr) { - item = Objects.requireNonNull(attr.item, " attribute 'item' must not be null.") + if (attr.item && attr.items) { + throw new IllegalArgumentException(" cannot have both 'item' and 'items' attributes.") + } + this.items = attr.item ? [attr.item] : attr.items ?: [] } @Override protected View getDelegate() { return { Writer w -> - if (item.respondsTo('renderTo', [Writer] as Class[])) { - item.renderTo(w) - } else if (item.respondsTo('render')) { - w << item.render() - } else { - throw new IllegalArgumentException( - ' must use an item which responds to either renderTo(Writer) or render().' - ) + items.each { + if (it instanceof Closure) { + it = it() + } + if (it.respondsTo('renderTo', [Writer] as Class[])) { + it.renderTo(w) + } else if (it.respondsTo('render')) { + w << it.render() + } else { + def cw = new DefaultComponentWriter(w, context.renderContext, context) + cw << it + } } } } diff --git a/web-view-components/src/test/groovy/groowt/view/component/web/lib/OutletTests.groovy b/web-view-components/src/test/groovy/groowt/view/component/web/lib/OutletTests.groovy index df7915b..1bb5c99 100644 --- a/web-view-components/src/test/groovy/groowt/view/component/web/lib/OutletTests.groovy +++ b/web-view-components/src/test/groovy/groowt/view/component/web/lib/OutletTests.groovy @@ -1,6 +1,5 @@ package groowt.view.component.web.lib - import groowt.view.component.web.WebViewComponentContext import groowt.view.component.web.WebViewComponentScope import org.junit.jupiter.api.Test diff --git a/web-view-components/src/test/groovy/groowt/view/component/web/lib/RenderTests.groovy b/web-view-components/src/test/groovy/groowt/view/component/web/lib/RenderTests.groovy index 7e18147..0e46897 100644 --- a/web-view-components/src/test/groovy/groowt/view/component/web/lib/RenderTests.groovy +++ b/web-view-components/src/test/groovy/groowt/view/component/web/lib/RenderTests.groovy @@ -1,5 +1,7 @@ package groowt.view.component.web.lib + +import groowt.view.component.web.BaseWebViewComponent import org.junit.jupiter.api.Test class RenderTests extends AbstractWebViewComponentTests { @@ -20,6 +22,14 @@ class RenderTests extends AbstractWebViewComponentTests { } + static final class Hello extends BaseWebViewComponent { + + Hello() { + super('Hello, World!') + } + + } + @Test void renderToExample() { doTest(''' @@ -44,4 +54,18 @@ class RenderTests extends AbstractWebViewComponentTests { ) } + @Test + void rendersComponent() { + doTest('} />', 'Hello, World!', context { + configureRootScope { + addWithNoArgConstructor(Hello) + } + }) + } + + @Test + void rendersItems() { + doTest('', '012') + } + }