Resource Types
- Introduction
- Choose a Unique Resource Type Name
- Adding the Resource Type to a Publication
- Providing One or More Sample XML Documents
- Providing an XML Structure Definition
- Creating a Workflow Schema
- Cache Expiration Time
- The Resource Type Definition
- I18n for the Resource Type Label
- Define a Custom Menubar
- Formats
- Presentation
Introduction
A resource type defines a certain (XML or binary) source format, together with processing options. It typically consists of
- an XML structure definition (e.g., Relax NG), if the resource type is XML-based,
- some presentation pipelines,
- some presentation XSLT stylesheets,
- usecases to manipulate documents.
All of these can be shared between several resource types.
The information describing a resource type is managed by a
ResourceType
service. The default implementation is ResourceTypeImpl
.
It implements ThreadSafe
, which ensures that only a single instance of every resource type is created.
It is not possible to declare multiple resource types with the same name.
Choose a Unique Resource Type Name
You should choose a reasonable name for your resource type.
In the examples, we use the name profile (page with information about a person).
Adding the Resource Type to a Publication
The resource types used by a publication are declared in publication.xml
,
including the assignment of a workflow schema to a resource type. You have to add your
resource type to the <resource-types>
section of this file:
<publication> ... <resource-types> <resource-type name="xhtml" workflow="fallback://config/workflow/workflow.xml"/> <resource-type name="homepage" workflow="fallback://config/workflow/workflow.xml"/> <resource-type name="links" workflow="fallback://config/workflow/workflow.xml"/> <resource-type name="profile" workflow="fallback://config/workflow/workflow.xml"/> ... </resource-types> ... </publication>
You can add references to any resource types configured in
<lenya-webapp>/WEB-INF/cocoon.xconf
(see below),
containing
- resource types provided by modules,
- resource types of template publications, and
- resource types of the publication itself.
Providing One or More Sample XML Documents
If you want to enable users to create new resources belonging to your resource type, it is useful to provide one more more sample XML documents.
The sample document(s) are typically placed in the directory
$MODULE_HOME/samples
.
You can choose arbitrary filenames, but for a single sample
it is recommended to use the resource type name
(e.g., profile.xml
).
There are two ways of declaring the samples. The first option is very convenient if you don't need custom samples per publication. You just add the samples to the resource type declaration:
<component-instance name="profile" ... ... <sample-name name="Empty Profile" mime-type="application/xml"> fallback://lenya/modules/profile/samples/empty.xml</sample-name> <sample-name name="Example Profile" mime-type="application/xml"> fallback://lenya/modules/profile/samples/example.xml</sample-name> ... </component-instance>
The second option allows you to specify a file where the samples declarations are stored. This enables you to override this file in your publications, providing a different sample list per publication:
<component-instance name="profile" ... ... <samples uri="fallback://lenya/modules/profile/samples/samples.xml"/> ... </component-instance>
The samples.xml
file uses the same syntax:
<?xml version="1.0" encoding="utf-8"?> <samples> <sample-name name="Empty Profile" mime-type="application/xml"> fallback://lenya/modules/profile/samples/empty.xml</sample-name> <sample-name name="Example Profile" mime-type="application/xml"> fallback://lenya/modules/profile/samples/example.xml</sample-name> </samples>
Providing an XML Structure Definition
This step is only needed if you want to edit resources with Lenya or validate them after they have been imported or manipulated. The type of the structure definition (XML Schema, Relax NG, ...) depends on the editor or validator you want to use. For instance, the BXE WYSIWYG editor requires a Relax NG document.
The structure definition document is typically placed in the directory
$MODULE_HOME/resources/schemas
. The name
of the file is arbitrary, but it is recommended to use the
resource type name (e.g., profile.rng
).
Creating a Workflow Schema
If your resources should have a workflow, you have to add a workflow
schema for your resource type as described in
Workflow Configuration.
A workflow schema can be shared between multiple resource types.
The workflow schema is assigned to a resource type in
$PUB_HOME/config/publication.xml
(see section Adding Resource Types to a Publication).
Cache Expiration Time
For each resource type, you can configure how long the documents shall be cached by the client, for instance:
<expires seconds="3600" />
This value can be accessed via the getExpires()
methods of the
ResourceType
and Document
interfaces. You can use the
header action to set the corresponding HTTP response header in your publication:
<map:act type="set-header"> <map:parameter name="Expires" value="{date-iso8601-rfc822:{doc-info:{pubId}:{area}:{uuid}:{language}:expires}}"/> </map:act>
The Resource Type Definition
To declare a custom resource type and assign the creator, schema etc. to it,
add the component instance to an XPatch file (e.g.,
$MODULE_HOME/config/cocoon-xconf/resourcetype-profile.xconf
):
<xconf xpath="/cocoon/resource-types" unless="/cocoon/resource-types/component-instance[@name = 'profile']"> <component-instance name="profile" logger="lenya.resourcetypes.profile" class="org.apache.lenya.cms.publication.ResourceTypeImpl"> <schema src="fallback://lenya/modules/profile/resources/schemas/profile.rng" language="http://relaxng.org/ns/structure/0.9"/> <sample-name name="Empty Profile" mime-type="application/xml"> fallback://lenya/modules/profile/samples/empty.xml</sample-name> <sample-name name="Example Profile" mime-type="application/xml"> fallback://lenya/modules/profile/samples/example.xml</sample-name> <link-attribute xpath="//*[namespace-uri() = 'http://foo.bar.org/profile']/@href"/> <format name="xhtml" uri="cocoon://modules/profile/profile.xml"/> <expires seconds="3600" /> </component-instance> </xconf>
This XPatch file will be used when the publication is deployed (e.g., when you issue
a ./build
command). Its contents will be patched into
<lenya-webapp>/WEB-INF/cocoon.xconf
.
I18n for the Resource Type Label
There is a convention that the message key resourceType-{name} is used for a human-readable, translated resource type label:
<?xml version="1.0" encoding="UTF-8"?> <catalogue xml:lang="en" xmlns:xhtml="http://www.w3.org/1999/xhtml"> <message key="resourceType-profile">Profile</message> </catalogue>
Define a Custom Menubar
If you want to use a custom menubar for your resource type, follow the guidelines on the page The Lenya Menubar. Typically, a menubar is shared between multiple resource types. Small customizations can be achieved with Java code in the menubar XSP.
To let the user create new resources using the DefaultBranchCreator
,
you have to add the following menu item:
<item uc:usecase="sitemanagement.create" href="?doctype=profile"> <i18n:translate> <i18n:text>New ... Document</i18n:text> <i18n:param><i18n:text>resourceType-profile</i18n:text></i18n:param> </i18n:translate> </item>
Formats
A resource type provides a set of formats to provide different ways of presenting content documents.
The formats are defined in the resource type declaration in
$MODULE_HOME/config/cocoon-xconf/resourcetype-profile.xconf
:
<format name="xhtml" uri="cocoon://modules/profile/xhtml.xml"/> <format name="include" uri="cocoon://modules/profile/xhtml-inline.xml"/>
The following figure illustrates some usage examples of formats:
- Example A shows the most typical case - a msg (message) document is rendered using the format xhtml to be displayed as page content.
- In example B , the format teaser is used to render teaser versions of the msg documents to be displayed in the sidebar. This is usually done using an include mechanism (see below).
- In example C , a news document includes the teaser versions of message documents. The news document in turn provides the format xhtml to be rendered as page content.
The uri
attribute of the format
element may refer to an arbitrary URL,
which is typically a request into the module itself. This URI is matched inside the module
sitemap (in our case, modules/profile/sitemap.xmap
).
There are two ways in which the format can be requested:
- for the current document - without parameters
- for a specific document - with the parameters
/{pubId}/{area}/{uuid}/{language}
Typically, an XSLT is applied to the content document to transform
it into another format (XHTML, XSL-FO, ...). In the following example,
the name of the XSLT stylesheet is supposed to end with the format name
(e.g., profile2xhtml.xsl
):
<!-- apply a format --> <!-- {format}.xml (current document) --> <map:match pattern="*.xml"> <map:generate src="cocoon:/{1}/{page-envelope:publication-id}/ \ {page-envelope:area}/ \ {page-envelope:document-uuid}/ \ {page-envelope:document-language}"/> <map:serialize type="xml"/> </map:match> <!-- {format}.xml/{pubId}/{area}/{uuid}/{language} (specific document) --> <map:match pattern="*.xml/*/*/*/*"> <map:generate src="lenya-document:{4},lang={5}{link:rev}"/> <map:transform src="fallback://lenya/modules/profile/xslt/profile2{1}.xsl"> <map:parameter name="rendertype" value="{request-param:rendertype}"/> <map:parameter name="nodeid" value="{doc-info:{2}:{3}:{4}:{5}:nodeName}"/> <map:parameter name="language" value="{4}"/> </map:transform> <map:serialize type="xml"/> </map:match>
To request a formatted document, you can use the format parameter of the
site:
and lenya-document:
protocols. You can issue such
a request from an arbitrary sitemap (e.g., from your publication sitemap or from
a different module sitemap).
<!-- aggregate navigation components and XHTML-formatted content --> <map:aggregate element="cmsbody"> <map:part src="cocoon://modules/sitetree/{2}/{3}/breadcrumb/{5}.xml"/> <map:part src="cocoon://modules/sitetree/{2}/{3}/tabs/{5}.xml"/> <map:part src="cocoon://modules/sitetree/{2}/{3}/menu/{5}.xml"/> <map:part src="cocoon://modules/sitetree/{2}/{3}/search/{5}.xml"/> <map:part src="lenya-document:{page-envelope:documente-uuid}?format=xhtml"/> </map:aggregate>
Another usage scenario is to include formatted documents in other documents, e.g. as a teaser or summary (see the figure above):
<ci:include src="site:/{$language}{$path}?format=teaser"/>
<ci:include src="lenya-document:{$uuid}?format=teaser"/>
Since formats allow you to select the presentation style of a document
on demand, you can use them as layout templates. But unfortunately formats have to
be declared in cocoon.xconf
, so you can't add new templates at
runtime with this approach at the moment. Here's an example how to use formats to select templates:
-
Set the Dublin Core element
format
when you create the document, e.g. using a combo box. We use the Dublin Core for simplicity here, for a cleaner approach you should define your own meta data element set. -
In the resource type module, provide an XSLT stylesheet
{resource-type}2{format}.xsl
for each format (see above) -
Add the format parameter to the
lenya-document
call:<map:generate src="lenya-document:{page-envelope:uuid}?format={dublincore:format}"/>
Presentation
To make your resources available as HTTP pages, you have to add the appropriate pipelines and XSLT stylesheets. In general, there are no restrictions.
The pipelines have to be placed in
$MODULE_HOME/sitemap.xmap
. The stylesheets are typically located in
$MODULE_HOME/xslt/
and named {resource-type}2{format}.xsl
(e.g., profile2xhtml.xsl
).
In the case of the xhtml format, the stylesheet is supposed to generate a valid XHTML document (in the XHTML namespace). The output of other formats depends on the purpose of the respective format.