<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>

Renderers


Setup

Renderers integrate with the application as a Struts Plugin. In the same way as Tiles or even Struts Validator you have to declare it's use in the module's configuration. Since the renderer's configuration is common to all modules the declaration of the plugin is made only in struts-default.xml. Here is an extract of the module configuration:
<plug-in className="pt.ist.fenixWebFramework.renderers.plugin.RenderersPlugin">
    <set-property property="config" 
                  value="/WEB-INF/fenix-renderers-config.xml"/>
    <set-property property="schemas" 
                  value="/WEB-INF/fenix-renderers-schemas.xml"/>
    <set-property property="metaObjectFactory" 
                  value="net.sourceforge.fenixedu.presentationTier.renderers.factories.FenixMetaObjectFactory"/>
    <set-property property="userIdentityFactory" 
                  value="net.sourceforge.fenixedu.presentationTier.renderers.factories.FenixUserIdentityFactory"/>
    <set-property property="schemaFactory" 
                  value="net.sourceforge.fenixedu.presentationTier.renderers.factories.FenixSchemaFactory"/>
</plug-in>
The plugin must be configured with 5 properties:
config
The context relative location of the renderers configuration
schemas
The context relative location of the schemas defintions
metaObjectFactory
Factory that creates meta objects that wrap the real objects
userIdentityFactory
Factory that creates a user identity to associate to the current presentation
schemaFactory
Factory that will create the default schemas for objects when no schema is provided
As one of the simplest presentations of a domain object is a link to the object details you need to do an additional modification to the module's struts configuration: you need to register the ViewObjectAction. The necessary modification is as follow:
<action path="/domain/view" 
        type="net.sourceforge.fenixedu.presentationTier.renderers.actions.ViewObjectAction">
    <forward name="show" path="domain.view"/>
</action>
As you can see this requires another modification in the corresponding module's tiles definitions. An example of the required modification is:
<definition name="domain.view" extends="definition.manager.masterPage" >
    <put name="body" value="/commons/renderers/view.jsp" />
</definition>

Note that the tiles definition example extends a definition only available in the manager module. Using the conventions of the Fénix project you would extend "defintion.<module name>.masterPage" were <module name> is replaced by the corresponding module name.

Fundamentals

There are three fundamental concepts:

Renderers are Java classes that have as it's main task to create an html component from a given datum, that is, a renderer is given some sort of data, like a number or a more complex object, and the result of rendering that object is an HtmlComponent. Renderers can have properties (through standard getters and setters) that allow them to be configured and, through that, to configure the result HtmlComponent.

Each renderer can be associated with a specific type. This means that whenever the given type should be presented (or renderer) the associated renderer is used. Nevertheless, often we need to present the same type in many different ways and allow to choose in each case wich of those ways we want. The conjuntion of a name, a renderer, and some properties for a renderer is a layout.

Every renderer as access to the object that needs to be presented and to the associated meta-object. This meta-object represents the object as asked to be presented, that is, contains at least the information in the schema. The structure of the meta-object should be obeyed. Among other things the meta-object contains information about which parts of the object should be presented. This information is represented through a schema. Schemas indicate, for complex objects, which slots should be shown, how they should be presented, and more.

The renderers configuration is global to all modules and is divided in two files:

Each particular file together with the referenced DTD has some documentation that should allow you to understand how to extend it.

Examples

The following examples intend to explain the use and extension of the renderers though simple, concrete, and increasingly challenging situations.