= 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.web.WebViewComponent
import groowt.view.web.lib.*
import groowt.view.web.runtime.*

class MyComponentTemplate implements ComponentTemplate {

    Closure getRenderer() {
        return { ComponentContext componentContext, ComponentWriter out ->
            // <1>
            final RenderContext renderContext = new DefaultWebViewComponentRenderContext(componentContext, out)
            componentContext.setRenderContext(renderContext)
            out.setRenderContext(renderContext)
            out.setComponentContext(renderContext)

            out.append 'Hello from simple text!' // <2>

            out.append "Hello from GString!" // <3>

            // <4>
            ComponentContext.Resolved c0Resolved // <5>
            try {
                c0Resolved = renderContext.resolve('MySubComponent', MySubComponent) // <6>
            } catch (ComponentResolveException c0ResolveException) { // <7>
                c0ResolveException.template = this
                c0ResolveException.line = 1
                c0ResolveException.column = 1
                throw c0ResolveException
            }

            WebViewComponent c0 // <8>
            try {
                c0 = renderContext.create( // <9>
                        c0Resolved,
                        [greeting: 'Hello, World!'],
                        "Some constructor arg",
                        WebViewComponentChildCollectorClosure.get(this) { c0cc ->
                            c0cc.add 'JString child.' // <10>
                            c0cc.add "GString child"

                            ComponentContext.Resolved c1Resolved
                            try {
                                c1Resolved = renderContext.resolve('h1') // <11>
                            } catch (ComponentResolveException c1ResolveException) {
                                c1ResolveException.type = IntrinsicHtml // <12>
                                c1ResolveException.template = this
                                c1ResolveException.line = 1
                                c1ResolveException.column = 10
                                throw c1ResolveException
                            }

                            WebViewComponent c1
                            try {
                                c1 = renderContext.create(
                                        c1_resolved,
                                        WebViewComponentChildCollectorClosure.get(this) { c1cc ->
                                            c1cc.add "$greeting"
                                        }
                                )
                            } catch (ComponentCreateException c1CreateException) {
                                c1CreateException.template = this
                                c1CreateException.line = 1
                                c1CreateException.column = 1
                            }

                            c0cc.add c1
                        }
                )
            } catch (ComponentCreateException c0CreateException) {
                c0CreateException.template = this
                c0CreateException.line = 1
                c0CreateException.column = 1
                throw c0CreateException
            }

            // append it
            out.append c0
        }
    }
}
----
<1> Initialize the contexts.
<2> Appending a plain old java string (jstring) to `out`.
<3> Appending a GString to `out`.
<4> Now begins a component 'block', where a component is resolved, created, and either rendered or appended
    to a child collector (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 a few things:
. The relevant instance of `ComponentContext.Resolved`.
. Any attributes for the component, passed as a `Map`.
. Any arguments from the component constructor.
. A `WebViewComponentChildCollectorClosure`, which is a 'marker' subclass of `Closure`
(so that constructor args ending with a closure don't get confused), which simply collects
the children of the component.
<10> For children, we add the value of the child, rather than appending it directly to `out`.
The collector itself will be given the `out` writer from the `context`, which will then
supply the parent with the ability to render to out. This way the parent doesn't ever have to worry about `out` itself
(though if the parent wants access to `out` (for example, it is using a non-wvc template) it can access the out writer
from the context).
<11> Here, a string type is passed, since all lowercase type names are treated as string types in web view components.
<12> Because this is an intrinsic html element, we set the type here.
<13> Finally, our child component is added as a `Closure` which accepts the component back again and appends
it to out.

== 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
