113 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			113 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
= 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 { 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<WebViewComponent>`.
 | 
						|
<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
 |