using afEfan::EfanMeta
** Implement to define an 'efanXtra' component.
**
** Whereas 'efan' has 'EfanRenderer' instances, 'efanXtra' has 'EfanComponent' instances.
mixin EfanComponent {
** Meta data about the compiled efan templates
EfanMeta efanMeta() {
this -> _efan_templateMeta
}
** The main render method. 'initArgs' are passed to the '@InitRender' lifecycle method.
**
** In normal use, 'bodyFunc' is only passed from within a template.
** It is executed when 'renderBody()' is called.
** Use it for enclosing content in *Layout* templates. Example:
**
** pre>
** ...
** <%= app.renderLayout() { %>
** ... my body content ...
** <% } %>
** ...
** <pre
Str render(Obj?[]? initArgs := null, |->|? bodyFunc := null) {
// execute the component lifecycle
((ComponentRenderer)(this -> _efan_renderer)).render(this, initArgs, bodyFunc)
}
** Call from within your template to render the body of the enclosing efan template.
** Example, a simple 'layout' efan template may look like:
**
** pre>
** syntax: html
** <html>
** <body>
** <%= renderBody() %>
** </body>
** </html>
** <pre
Str renderBody() {
((ComponentRenderer)(this -> _efan_renderer)).renderBody(this)
}
** Renders the efan template. Not meant to be invoked by you, the user!
**
** Override to bypass template rendering and return your own generated content.
** Useful for simple components.
virtual Str renderTemplate() {
// call the actual efan compiler render method
this -> _efan_render(null)
}
** Returns a unique ID for this component based on the lib and type name.
Str componentId() {
this -> _efan_componentId
}
** Returns 'componentId()'
@NoDoc
override Str toStr() { componentId }
}