5.2. Presentation

The standard presentation mechanism for content items involves generating XML and applying an XSLT transform to generate output markup. An example of the XML output for a content item can be found at Section 5.4.5 Presentation XML Output Example.

5.2.1. XML Generation

The DomainObjectXMLRenderer class is used to generate an XML representation of a content item based on it's object type metadata (as defined in the PDL). Exactly which properties make it through to the XML is controlled by registering instances of the DomainObjectTraversalAdapter class against the object type. While you can do this explicitly, it is preferrable and faster to write an XML file specifying inclusion/exclusion rules attributes and associations of a type.

Place the XML rule definition files in $WEBAPP/WEB-INF/traversal-adapters/. Within this directory, the file should be in a directory matching the package name of the content type and the file should match the name of the primary content type. So for the BankNote content type, the file would be $WEBAPP/WEB-INF/traversal-adapters/com/example/moneymachine/cms/\ contenttypes/BankNote.xml. The server will read in these XML rule definition files upon startup, then construct and register instances of the SimpleDomainObjectTraversalAdapter class.

The purpose of the rule definition file is to instruct the XML renderer why PDL properties need to be output. There are two ways of doing this: list by inclusion, or list by exclusion. Compare this to e.g. Apache's access control allow/deny vs deny/allow options. For attributes, list by exclusion is the default behaviour, since once you've retreived an object there is no SQL overhead in outputting all its attributes. Conversly, for associations, list by inclusion is the default, since each association you retrieve incurrs at least one SQL query.

What follows is a description of each element. There is a full schema (Section 5.4.1 Content Type Definition Schema) and example XML document instance (Section 5.4.5 Presentation XML Output Example) you can refer to.

XML Renderer Rule Definitions

Adapters element

The root element in the definition is <xrd:adapters>. This is a container for one or more <xrd:adapter> elements - one for each type being defined. Typically you would only define rules for one content type in each file, however, if you had a pair of co-dependant content types you would define them both in a single file to ensure they are both loaded together. The attributes on this tag are used to specify the namespace and schema location for the elements which follow so that the processor can validate the document.

 <xrd:adapters xmlns:xrd="http://rhea.redhat.com/schemas/waf/\ 
xml-renderer-rules"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://rhea.redhat.com/schemas/waf/\ 
xml-renderer-rules xml-renderer-rules.xsd">
   ... adapters ...
 </xrd:adapters>
Adapter element

The xrd:adapter element defines the rules for a single object type, in a single use context. The objectType attribute specifies the persistent object type to which the rules apply. This will match the type itself, and any subtypes (unless the subtype registers its own rules). The context attribute specifies the use context of the rule. The metadata driven XML generator can be used in many different subsystems (Object export, search metadata, object display), each of which may need a different set of properties output. For the presentation of content items, the context is always com.arsdigita.cms.dispatcher.SimpleXMLGenerator.

  <xrd:adapter objectType="com.arsdigita.cms.Article"
                  context="com.arsdigita.cms.dispatcher.\
SimpleXMLGenerator">
     <xrd:attributes ...
     <xrd:associations ...
  </xrd:adapter>
Attributes element

The xrd:attributes element defines the rules for object attributes. An attribute is defined as any object property for which ObjectType#getProperty().isAttribute() returns true. The rule attribute defines whether the list of properties is a black list or white list (values exclude and include respectively). The default, if not specified, is exclude.

    <xrd:attributes rule="include">
      ... properties ...
    </xrd:attributes>
Association element

The xrd:associations element defines the rules for object associations. An association is defined as any object property for which ObjectType#getProperty().isAttribute() returns false. The rule attribute defines whether the list of properties is a black list or white list (values exclude and include respectively). The default, if not specified, is include.

    <xrd:associations rule="exclude">
      ... properties ...
    </xrd:associations>
Property element

One or more xrd:property elements can occurr within the xrd:attributes and xrd:attributes elements. Each rule specifies the name and path of a single object property in the name attribute. The path starts with the top level object being rendered and has an additional component for each association traversed. The last component is the name of the association or attribute to which this rule refers. So to refer to the content of the associated text asset in an article the path would be /object/textAsset/content. Since, some associations are recursive, you can specify a wildcard after the association name to get it to follow the entire hierarchy (albeit with the obvious performance implications for deep hierarchies). For example, to pull out all children of the categories associated with an item, the path would be /object/categories/related*.

  <xrd:property name="/object/id"/>

5.2.2. XSLT Transformation

When transforming the XML document to generate the final output (be it HTML, WML, text, etc), there can be a number of different presentations required depending on the use context. Likewise, different use contexts may use the same presentation. Thus it is useful to decouple presentation style from the use context. As a concrete example, consider four use contexts: preview, view, summary and accessible.

View and preview would typically use the same presentation style and summary while accessible might use the same low-fi style. The XSL file rules for a single content type should be put in the directory $WEBAPP/static/content-types/. Within this directory, the file should be in a directory matching the package name of the content type and the file should match the name of the primary content type. So for the BankNote content type, the file would be $WEBAPP/static/content-types/com/example/moneymachine/cms/contenttypes/\ BankNote.xml.

The server will look for all files in the /static/cms/content-types directory and then generate a single file containing appropriate xsl:import statements. This single file will be imported into the main CMS stylesheet to make all the content types available.

5.2.2.1. Presentation Modes

Default CMS styling expects each content type to provide templates for two different presentation modes, graphical and text only. Templates for each are provided by matching on the XPath cms:item[objectType='com.example.moneymachine.cms.contenttypes.BankNote'] with a mode of cms:CT_graphics or cms:CT_text respectively. To allow explicit use of the templates, they should also contain a name attribute of the form 'cms:CT_[mode]_[object type]', where '[mode]' is either 'graphics' or 'text', and '[object type]' is the PDL object type where '.' has been replaced with '_'. So for example:

  <xsl:template match="cms:item[objectType='com.arsdigita.cms.contenttypes.\
Agenda']" mode="cms:CT_graphics"
     name="cms:CT_graphics_com_arsdigita_cms_contenttypes_Agenda" >
    ... full graphics renderering goes here ...
  </xsl:template>

  <xsl:template match="cms:item[objectType='com.arsdigita.cms.contenttypes.\
Agenda']" mode="cms:CT_text"
     name="cms:CT_text_com_arsdigita_cms_contenttypes_Agenda" >
    ... text only renderering goes here ...
  </xsl:template>

A full example XSLT template can be found in Section 5.4.6 Presentation XSLT Example.