| <?xml version="1.0"?> |
| <!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.0//EN" "../../dtd/document-v10.dtd"> |
| |
| <document> |
| <header> |
| <title>Configuring the Cocoon Portal</title> |
| <authors> |
| <person email="cziegeler@apache.org" name="Carsten Ziegeler"/> |
| <person email="jgreenyer@s-und-n.de" name="Joel Greenyer"/> |
| </authors> |
| <notice>This document is under development.</notice> |
| <abstract> |
| This document describes the use and configuration |
| of the (new) cocoon portal block. |
| </abstract> |
| </header> |
| <body> |
| <s1 title="Introducing the Cocoon Portal"> |
| <p> |
| This document describes the use and configuration |
| of the (new) cocoon portal that you can find in the "portal" block. |
| (Don't mix this with the older portal version that you can |
| find in the "portal-fw" block.) |
| </p> |
| <s2 title="Important parts of the Cocoon Portal"> |
| <p>TBD |
| </p> |
| </s2> |
| <s2 title="How is a portal page created by Cocoon?"> |
| <p>TBD |
| </p> |
| </s2> |
| <s2 title="I want to build my own portal! An approach"> |
| <p>TBD |
| </p> |
| </s2> |
| </s1> |
| |
| <s1 title="Configuring the Portal contents"> |
| <p> |
| The configuration of a coplet is done in several steps that are outlined |
| in the next chapters. |
| </p> |
| <s2 title="Configuring Coplets"> |
| <p> |
| Configuring coplets is like defining a class and creating their instances. |
| So in fact, you define the available coplets (= classes) and each portal |
| view gets some instances of these coplets. |
| </p> |
| <s3 title="Available Coplet Types"> |
| <p> |
| Before you can define your available coplets, you have to define the |
| available coplet types, or the so called coplet base data. The current |
| sample contains an XML document for this: |
| </p> |
| <source> |
| <![CDATA[... |
| <coplets> |
| <coplet-base-data id="URICoplet"> |
| <coplet-adapter>uri</coplet-adapter> |
| </coplet-base-data> |
| </coplets> |
| ...]]> |
| </source> |
| <p>In the example above, we define one coplet type, the <em>URICoplet</em>, |
| that uses the <em>uri coplet adapter</em>. By this we define a type, |
| that uses URIs to get the content of a coplet.</p> |
| <p>You can add different coplet types with additional configuration here, |
| but rarely have to touch this file.</p> |
| </s3> |
| <s3 title="Available Coplets"> |
| <p> |
| Based on the coplet types, you can define the available coplets in your |
| portal application (= classes). In the example portal an own configuration |
| file contains these so called coplet datas. Here is an excerpt: |
| </p> |
| <source> |
| <![CDATA[... |
| <coplets> |
| <coplet-data id="CZ Weblog" name="standard"> |
| <title>CZ's Weblog</title> |
| <coplet-base-data>URICoplet</coplet-base-data> |
| <attribute> |
| <name>uri</name> |
| <value xsi:type="java:java.lang.String" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">cocoon:/news/liverss?feed=http://radio.weblogs.com/0107211/rss.xml</value> |
| </attribute> |
| <attribute> |
| <name>buffer</name> |
| <value xsi:type="java:java.lang.Boolean" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">true</value> |
| </attribute> |
| <attribute> |
| <name>error-uri</name> |
| <value xsi:type="java:java.lang.String" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">cocoon:/news/CZ_weblog.rss</value> |
| </attribute> |
| </coplet-data> |
| </coplets> |
| ...]]> |
| </source> |
| <p>Each coplet data contains a unique id and additional configuration. A required |
| configuration is the underlying coplet base data. In the example above, |
| the <em>URICoplet</em> is used here. |
| </p> |
| <p>The above configured coplet data requires some configuration, like the |
| URI to invoke to fetch the content for this coplet. This configuration is |
| passed in the different attributes you see above. Each attribute has |
| a name and value. |
| </p> |
| <p>The set of coplet datas defines the set of available coplets a user can |
| choose from. If a user chooses to view a coplet, an instance of this coplet |
| data is created. If, e.g. the user chooses the same coplet twice, |
| two instances are created. This is useful for configurable coplets where |
| the user can choose the same coplet with different configurations. |
| </p> |
| </s3> |
| <s3 title="Selected Coplets"> |
| <p> |
| The selected coplets are described by the set of coplet instance datas. |
| </p> |
| <source> |
| <![CDATA[... |
| <coplets> |
| <coplet-instance-data id="CZ Weblog-1" name="standard"> |
| <coplet-data>CZ Weblog</coplet-data> |
| </coplet-instance-data> |
| </coplets> |
| ...]]> |
| </source> |
| <p> |
| The coplet instance data refers to its coplet data by specifying the |
| unique ID. The instance itself has a unique ID as well that is referenced |
| from the portal view. |
| </p> |
| <p> |
| In addition, a coplet instance data could have own configuration information. |
| </p> |
| </s3> |
| </s2> |
| <s2 title="Configuring the arrangement of the defined Coplets"> |
| <p> |
| The portal view defines the ordering and arrangement of the coplets. This |
| view is defined in a hierarchical manner by nesting layout objects. At |
| each place, a coplet is located, a reference to a coplet instance data |
| is included. |
| </p> |
| <p> |
| The Cocoon portal provides several predefined layout elements you can use |
| for your portal view to create a nice layout: |
| </p> |
| <ul> |
| <li>row - a row of items</li> |
| <li>column - a column of items</li> |
| <li>tab - a tab</li> |
| </ul> |
| <p> |
| These are the "high-level" objects, you can use to define your |
| structure. You can nest them in any order to create a complex |
| layout. The layout is defined in an XML document as well, so let's |
| have a look at an example: |
| </p> |
| <source> |
| <![CDATA[... |
| <composite-layout name="row"> |
| <item> |
| <coplet-layout name="coplet"> |
| <coplet-instance-data>Portal-Intro-1</coplet-instance-data> |
| </coplet-layout> |
| </item> |
| <item> |
| <coplet-layout name="coplet"> |
| <coplet-instance-data>Portal-Bottom-1</coplet-instance-data> |
| </coplet-layout> |
| </item> |
| </composite-layout> |
| ...]]> |
| </source> |
| <p> |
| In the example above, we define a row containing two coplets. This is done |
| by selecting the row layout and defining the childs (or items) of this |
| layout. In this case the items are two new layout objects, the coplet |
| layouts that can contain a coplet. The coplet layout has a reference |
| to the coplet instance data. |
| </p> |
| </s2> |
| <s2 title="The Rendering Process"> |
| <p> |
| Each layout object has a defined renderer that is used to render this |
| layout object. You can find the renderers in the cocoon.xconf. Each renderer |
| has a unique name that is used to identify this renderer. |
| </p> |
| <p> |
| A central component, the layout factory (configured in the cocoon.xconf as |
| well), contains a list of all available layout objects, like the row, |
| the column etc. The configuration for each layout object contains also |
| the corresponding renderer information. So, here is the configuration |
| which renderer will be used to render the layout object. |
| </p> |
| <p> |
| A renderer itself can be configured in various ways. The portal engine uses |
| so called aspects (don't mess them with AOP), that are used to enhance |
| to features of renderer, allowing - simplifying - a multiple inheritance |
| which is not possible in Java. Have a look at the cocoon.xconf for |
| the different renderer configurations. |
| </p> |
| </s2> |
| </s1> |
| |
| <s1 title="Create a new skin for your portal"> |
| <p>This section will explain the concepts of the portal layout, |
| considering the <code>skins/basic/</code> skin provided with cocoon, |
| and will describe how to create a new skin by extending the |
| existing stylesheets.</p> |
| <note>The skin path can be changed in the portal's sitemap. There is |
| a <code>global-variable</code> specifying the path to the skin folder.</note> |
| <p>The basic cocoon portal skin is a nice and simple example how to visualize a portal. |
| There are several elements that allow to customize the look and feel of the portal. |
| A portal with the basic skin consists of </p> |
| <ul> |
| <li>a <em>header</em></li> |
| <li>a <em>tab row</em></li> |
| <li>a <em>content section</em> containing the coplet windows</li> |
| <li>and a <em>footer </em></li> |
| </ul> |
| <figure alt="Parts of the portal" height="300" src="images/portal-parts.gif" width="400"></figure> |
| <p>The tab row is actually a part of the content section. As well, a tab row can |
| be provided to any coplet window.</p> |
| <s2 title="The skin's stylesheets"> |
| <p>If we take a look at the <code>skins/basic/styles</code> directory, we |
| find a number of stylesheets: |
| </p> |
| <ul> |
| <li><code>portal-page.xsl</code>: Creates final HTML page</li> |
| <li><code>tab.xsl</code>: layout of the tab row.</li> |
| <li><code>window.xsl</code>: coplet window layout</li> |
| <li><code>column.xsl</code>: layout of a column</li> |
| <li><code>row.xsl</code>: layout of a row</li> |
| <li><code>login-page.xsl</code>: layout of the login page</li> |
| </ul> |
| <p>The <code>window.xsl</code> stylesheet determines the layout of a |
| coplet window. Normally, a coplet window will contain a header row with a |
| title and buttons like minimize, close, etc.</p> |
| <p>These coplet windows are arranged in rows and columns to create |
| the arrangement typical for portals. There can be several rows per column |
| and several columns in the content section. So the thinking is a little |
| different than in usual HTML tables.</p> |
| <p>The content section or content row usually has a tab row located at the top |
| and the coplet windows are arranged below. The layout of the tabs is |
| specified in the <code>tab.xsl</code> stylesheet.</p> |
| <p>The <code>portal-page.xsl</code> stylesheet encapsulates the content section |
| with the tab row and allows to define a page header and a footer. |
| This is probably the first stylesheet we want to take a closer look at. |
| </p> |
| <note>The <code>tab.xsl</code>, <code>column.xsl</code>, |
| <code>row.xsl</code> and <code>window.xsl</code> stylesheets |
| are used by the portal components directly and won't be found |
| anywhere in the sitemap. The <code>cocoon.xconf</code> |
| defines which stylesheets will be used by the portal.</note> |
| </s2> |
| <s2 title="The portal-page.xsl"> |
| <p> |
| Here is the place to change the design of the header and footer row. |
| This stylesheet is used to construct the final HTML page, which displays |
| the portal. The code sample here displays the main template match node of the |
| stylesheet. |
| </p> |
| <source> |
| <![CDATA[... |
| <xsl:template match="/"> |
| <html> |
| <head> |
| <link type="text/css" rel="stylesheet" href="page.css"/> |
| </head> |
| <body> |
| <table bgColor="#ffffff" border="0" |
| cellPadding="0" cellSpacing="0" width="100%"> |
| <tbody> |
| |
| <!-- header row --> |
| <tr> |
| <td colspan="2"> |
| <table border="2" cellPadding="0" cellSpacing="0" width="100%"> |
| <tbody> |
| <tr> |
| <td colspan="2" noWrap="" height="10" bgcolor="#DDDDDD"> |
| </td> |
| </tr> |
| <tr> |
| <td bgcolor="#CCCCCC" height="100" align="center" |
| valign="middle" width="100%"> |
| <font size="80pt">Cocoon Portal</font> |
| </td> |
| </tr> |
| <tr> |
| <td colspan="2" noWrap="" height="10" bgcolor="#DDDDDD"> |
| </td> |
| </tr> |
| </tbody> |
| </table> |
| </td> |
| </tr> |
| |
| <!-- content/tab row --> |
| <tr> |
| <td> |
| <xsl:apply-templates/> |
| </td> |
| </tr> |
| |
| <!-- footer row --> |
| <tr> |
| <td colspan="2"> |
| <table border="2" cellPadding="0" cellSpacing="0" width="100%"> |
| <tbody> |
| <tr> |
| <td colspan="2" noWrap="" height="10" bgcolor="#DDDDDD"> |
| <img height="1" src="sunspotdemoimg-space.gif" width="1"/> |
| </td> |
| </tr> |
| <tr> |
| <td colspan="2" noWrap="" height="30" bgcolor="#CCCCCC"> |
| <img height="1" src="sunspotdemoimg-space.gif" width="1"/> |
| </td> |
| </tr> |
| </tbody> |
| </table> |
| </td> |
| </tr> |
| </tbody> |
| </table> |
| </body> |
| </html> |
| </xsl:template> |
| ...]]> |
| </source> |
| </s2> |
| <s2 title="The tab.xsl"> |
| <p>From the <code>portal-page.xsl</code> stylesheet, we will now |
| move upwards in the XSL transformation steps and take a look at the |
| stylesheet that was processed before, the <code>tab.xsl</code>.</p> |
| <p>Again, this source snippet shows the main template match node of the stylesheet:</p> |
| <source><![CDATA[... |
| <!-- Process a tab --> |
| <xsl:template match="tab-layout"> |
| <!-- ~~~~~ Begin body table ~~~~~ --> |
| <table border="2" cellpadding="0" cellspacing="0" width="100%"> |
| <!-- ~~~~~ Begin tab row ~~~~~ --> |
| <tr> |
| <td> |
| <table summary="tab bar" border="2" cellpadding="0" |
| cellspacing="0" width="100%"> |
| <tr vAlign="top"> |
| <xsl:for-each select="named-item"> |
| <xsl:choose> |
| <xsl:when test="@selected"> |
| <!-- ~~~~~ begin selected tab ~~~~~ --> |
| <td valign="middle" bgcolor="#DDDDDD"> |
| <b> |
| <a href="{@parameter}"> |
| <font color="#000000"> |
| <xsl:value-of select="@name"/> |
| </font> |
| </a> |
| </b> |
| </td> |
| <!-- ~~~~~ end selected tab ~~~~~ --> |
| </xsl:when> |
| <xsl:otherwise> |
| <!-- ~~~~~ begin non selected tab ~~~~~ --> |
| <td valign="middle" bgcolor="#CCCCCC" > |
| <div class="tab"> |
| <a href="{@parameter}"> |
| <xsl:value-of select="@name"/> |
| </a> |
| </div> |
| </td> |
| <!-- ~~~~~ end non selected tab ~~~~~ --> |
| </xsl:otherwise> |
| </xsl:choose> |
| </xsl:for-each> |
| <!-- ~~~~~ last "blank" tab ~~~~~ --> |
| <td width="99%" bgcolor="#CCCCCC" align="right"> |
| </td> |
| </tr> |
| </table> |
| </td> |
| </tr> |
| <!-- ~~~~~ End tab row ~~~~~ --> |
| |
| <!-- ~~~~~ Begin content row ~~~~~ --> |
| <tr> |
| <td bgcolor="#FFFFFF"> |
| <xsl:apply-templates/> |
| </td> |
| </tr> |
| <!-- ~~~~~ End content row ~~~~~ --> |
| </table> |
| </xsl:template> |
| ...]]></source> |
| <p>The first row that is created here contains the definition of the tabs. |
| The <code><xsl:choose></code> element differentiates between the |
| currently selected tab and all other tabs. The <code>@selected</code> |
| attribute is generated by the portal and can be accessed as shown |
| above. As well, the portal provides the tab's <code>@parameter</code> |
| (usually the tab's link) and <code>@name</code> attributes. </p> |
| |
| <note>Depending on the configuration of the portal, it is possible |
| that tabbed areas are nested inside each other. So be careful how a tab |
| row might look in the middle of another content section.</note> |
| |
| <p>Nice looking tabs can become pretty complex, take a look at the |
| <code>tab.xml</code> stylesheet in the <code>skins/common/</code> |
| skin to see another example.</p> |
| <p>Below the tabs, another table cell is defined that will be filled |
| with the contents of the tabbed area. This content will have been processed |
| by the <code>columns.xsl</code> stylesheet before - and before that by the |
| <code>row.xsl</code> stylesheet.</p> |
| </s2> |
| <s2 title="The column.xsl and row.xsl"> |
| <p>The <code>column.xsl</code> and <code>row.xsl</code> stylesheets |
| define the look of the tables in which the coplet windows will be placed. |
| Usually, nothing exciting happens in these stylesheets. Here is a listing of the |
| important parts, just to give a complete overview. |
| </p> |
| <p>The main template match node of the <code>column.xsl</code> stylesheet:</p> |
| <source><![CDATA[... |
| <!-- Process a Column --> |
| <xsl:template match="column-layout"> |
| |
| ... |
| |
| <table border="{$border}" cellSpacing="0" cellpadding="0" |
| width="100%"> |
| <xsl:if test="@bgcolor"> |
| <xsl:attribute name="bgcolor"> |
| <xsl:value-of select="@bgcolor" /> |
| </xsl:attribute> |
| </xsl:if> |
| <tr vAlign="top"> |
| <xsl:for-each select="item"> |
| <td> |
| <xsl:if test="@bgcolor"> |
| <xsl:attribute name="bgcolor"> |
| <xsl:value-of select="@bgcolor" /> |
| </xsl:attribute> |
| </xsl:if> |
| <xsl:if test="@width"> |
| <xsl:attribute name="width"> |
| <xsl:value-of select="@width" /> |
| </xsl:attribute> |
| </xsl:if> |
| <xsl:apply-templates /> |
| </td> |
| </xsl:for-each> |
| </tr> |
| </table> |
| </xsl:template> |
| ...]]></source> |
| <p>The main template match node of the <code>row.xsl</code> stylesheet:</p> |
| <source><![CDATA[... |
| <!-- Process a row --> |
| <xsl:template match="row-layout"> |
| |
| ... |
| |
| <table border="{$border}" cellSpacing="10" width="100%"> |
| <xsl:if test="@bgcolor"> |
| <xsl:attribute name="bgcolor"> |
| <xsl:value-of select="@bgcolor" /> |
| </xsl:attribute> |
| </xsl:if> |
| <xsl:for-each select="item"> |
| <tr vAlign="top"> |
| <xsl:if test="@bgcolor"> |
| <xsl:attribute name="bgcolor"> |
| <xsl:value-of select="@bgcolor" /> |
| </xsl:attribute> |
| </xsl:if> |
| <td> |
| <xsl:apply-templates /> |
| </td> |
| </tr> |
| </xsl:for-each> |
| </table> |
| </xsl:template> |
| ...]]></source> |
| </s2> |
| <s2 title="The window.xsl"> |
| <p>The <code>window.xsl</code> stylesheet determines the design of the coplet |
| windows and probably takes the most design effort compared to the other stylesheets. |
| A coplet window consists of a table header with the window title and a number |
| of buttons like close, minimize, maximize etc. The basic skin provides some |
| images in the <code>images/</code> subfolder. The rest of the window will |
| be filled with the coplet content, depending on the configuration of |
| the coplet.</p> |
| <p>A slightly more complex example can be found in the |
| <code>skins/common/</code> skin.</p> |
| |
| <p>The listing below shows the main template match node:</p> |
| <source><![CDATA[... |
| <xsl:template match="window"> |
| |
| ... |
| |
| <table border="2" cellSpacing="0" cellpadding="0" width="100%"> |
| <tr vAlign="top"> |
| <td bgColor="{$bgColor}" valign="middle"> |
| <font> |
| <xsl:attribute name="color">#ffffff</xsl:attribute> |
| <xsl:attribute name="face">Arial</xsl:attribute> |
| <xsl:attribute name="size">2</xsl:attribute> |
| <xsl:choose> |
| <xsl:when test="@title"> |
| <b><xsl:value-of select="@title"/></b> |
| </xsl:when> |
| <xsl:otherwise> |
| <b><xsl:value-of select="title"/></b> |
| </xsl:otherwise> |
| </xsl:choose> |
| </font> |
| </td> |
| <td align="right" bgColor="{$bgColor}"> |
| <xsl:if test="fullscreen-uri"> |
| <a href="{fullscreen-uri}"> |
| <img src="customize.gif" border="0" alt="Full Screen"/> |
| </a> |
| </xsl:if> |
| <xsl:if test="maxpage-uri"> |
| <a href="{maxpage-uri}"> |
| <img src="show.gif" border="0" alt="Max Page"/> |
| </a> |
| </xsl:if> |
| <xsl:if test="maximize-uri"> |
| <a href="{maximize-uri}"> |
| <img src="maximize.gif" border="0" alt="Maximize"/> |
| </a> |
| </xsl:if> |
| <xsl:if test="minimize-uri"> |
| <a href="{minimize-uri}"> |
| <img src="minimize.gif" border="0" alt="Minimize"/> |
| </a> |
| </xsl:if> |
| <xsl:if test="remove-uri"> |
| <a href="{remove-uri}"> |
| <img src="delete.gif" border="0" alt="Delete"/> |
| </a> |
| </xsl:if> |
| </td> |
| </tr> |
| <tr> |
| <td colSpan="2"> |
| <xsl:apply-templates select="content"/> |
| </td> |
| </tr> |
| </table> |
| </xsl:template> |
| ...]]></source> |
| </s2> |
| </s1> |
| |
| <s1 title="Further topics"> |
| <p> |
| </p> |
| </s1> |
| </body> |
| </document> |