= Component Template Specification == Compiled Component Template Code The following code represents a typical (transpiled) component template: [source, groovy] ---- package com.jessebrault.website import groowt.view.component.ComponentTemplate import groowt.view.component.context.ComponentContext import groowt.view.component.runtime.* import groowt.view.component.web.WebViewComponent import groowt.view.web.lib.* import groowt.view.web.runtime.* class MyComponentTemplate implements ComponentTemplate { Closure getRenderer() { return { WebViewComponentContext componentContext, ComponentWriter writer -> // <1> def renderContext = new DefaultWebViewComponentRenderContext(componentContext, writer) // <2> componentContext.setRenderContext(renderContext) writer.setRenderContext(renderContext) writer.setComponentContext(renderContext) writer << 'Hello from simple text!' // <3> writer << someProp // <3> writer << someMethod() // <3> // <4> def c0Resolved // <5> try { c0Resolved = renderContext.resolve('MySubComponent', MySubComponent) // <6> } catch (ComponentResolveException c0ResolveException) { // <7> c0ResolveException.template = this c0ResolveException.line = 1 c0ResolveException.column = 1 throw c0ResolveException } def c0 // <8> try { c0 = renderContext.create( // <9> c0Resolved, // <10> [greeting: 'Hello, World!'], // <11> ["Some constructor arg"] // <12> ) { c0childList -> // <13> c0childList << 'string child.' // <14> def c1Resolved try { c1Resolved = renderContext.resolve('h1') // <15> } catch (ComponentResolveException c1ResolveException) { c1ResolveException.template = this c1ResolveException.line = 1 c1ResolveException.column = 10 throw c1ResolveException } def c1 try { c1 = renderContext.create(c1_resolved) { c1cc -> c1cc << greeting } } catch (ComponentCreateException c1CreateException) { c1CreateException.template = this c1CreateException.line = 1 c1CreateException.column = 1 } c0childList << c1 } } catch (ComponentCreateException c0CreateException) { c0CreateException.template = this c0CreateException.line = 1 c0CreateException.column = 1 throw c0CreateException } writer << c0 } } } ---- <1> The render `Closure` receives a `ComponentContext` and a `ComponentWriter`. <2> A `RenderContext` is created which is then initialized with the values that the render `Closure` received. <3> Strings and expressions of every type (except components) are simply left-shifted into the `ComponentWriter`. <4> Now begins a component 'block', where a component is resolved, created, and eventually left-shifted into either a `ComponentWriter` or a children `List` (see below). <5> First, we define the `resolved` variable, of the type `ComponentContext.Resolved`. <6> Resolve it from the context. <7> If the context cannot resolve the component, it should throw a `ComponentResolveException`. We catch it here in order to set the template (`this`), line, and column information for debugging purposes. <8> Now we can start to create the component by first defining a variable for it. <9> The create function takes up to four parameters. <10> The relevant instance of `ComponentContext.Resolved` (required). <11> Attributes from the component, passed as a `Map` (required; if there are no attributes, an empty `Map` is passed). <12> Any arguments from the component constructor, passed as a `List` (required; if there are no arguments, an empty `List` is passed). <13> A `Closure` (optional), which receives an argument of `List` and simply collects the children of the component. <14> For children, we add the value of the child to the children `List`, rather than appending it directly to `out`. <15> Here, a string type is passed, since all lowercase type names are treated as string types in web view components. == Items requiring Groovy ASTNode position adjustment The following items all need to have their transpiled Groovy ASTNodes' positions adjusted to match the original source file, in case there is a Groovy compilation error involved. * JStrings * GStrings * Component types (Class and String expressions) * Attribute keys and values * Component constructor args