This page shows your how to write and/or configure a portlet. There are various approaches to reuse or write portlets, where Hippo's standard components can make things easy for you. Some options are:
nl.hippo.portal.cms.portlets, likeXSLTContentPortlet that show a repository XML document from repository,
after XSLT translation into HTML,XSLTListContentPortlet, also showing repository content,MenuPortlet, showing a menu from the site map in repository,BreadcrumbsPortlet, showing lineair site navigation.nl.hippo.hca.portlets, like the PollPortlet
showing a poll that is configured in the repository using Hippo CMS.nl.hippo.portal.cms.portlets.FreeMarkerContentPortlet.
You will need to create Freemarker
frontend script template and prepare a accompanying model in the portlet.org.apache.portals.bridges.common.GenericServletPortlet, from
javax.portlet.GenericPortlet or just implementing
javax.portlet.Portlet yourself. As long as it is
JSR-168
compliant, it will run on Hippo Portal.In this document we have chosen an example extending from
nl.hippo.portal.cms.portlets.FreeMarkerContentPortlet,
which is fairly easy to understand.
When writing a portlet that extends from nl.hippo.portal.cms.portlets.FreeMarkerContentPortlet,
the basic thing to do is to implement method createFreeMarkerModel,
which it called in the doView, which is in its turn
called during the render phase by javax.portlet.GenericPortlet.
Here a simple example portlet:
package com.example.portlets;
import javax.portlet.*;
import nl.hippo.portal.cms.portlets.FreeMarkerContentPortlet;
public class MyPortlet extends FreeMarkerContentPortlet {
@Override
protected Map<String,Object> createFreeMarkerModel(
RenderRequest request, RenderResponse response) {
// get a freemarker model map
Map<String,Object> model = super.createFreeMarkerModel(request, response);
// retrieve your data here
Object myData = ...;
// store the data to use in the freemarker template
model.put("myData", myData);
return model;
}
}
Although portlet rendering may be done in Java code by writing directly to
the response.getWriter() printwriter, many scripting techniques are available
that are easy to use and separate HTML from data model.
Normally a separate portlet page is used to render the HTML snippet that is the user interface.
The path to this portlet page is retrieved by the method getViewPage.
This method as present in the Hippo's BaseContentPortlet looks
subsequently for:
- a request parameter ViewPage,
- for a portlet preference ViewPage as configured in the portal page,
- for a portlet parameter ViewPage as configured in portlet.xml,
- for a default view page as set in code by setDefaultViewPage.
With our Freemarker example this path would be WEB-INF/templates/myportlet/view.ftl
and the content could look like this:
<div class="portlet">
<div class="portlet-section-header">MyPortlet</div>
<div class="portlet-section-body">
<#if myData??>
<div>Item 1: ${myData.item1}</div>
<div>Item 2: ${myData.item2}</div>
<div>Item 3: ${myData.item3}</div>
<#else>
<div>No data available.</div>
</#if>
</div>
Each portlet must be defined in the portlet.xml file
that resides in the WEB-INF directory of your portlet application.
Please refer to JSR 168
for more information on this deployment descriptor.
To define the example MyPortlet, having the correct ViewPage as preference parameter, the file should have this <portlet> element:
<portlet>
<portlet-name>MyPortlet</portlet-name>
<portlet-class>com.example.portlets.MyPortlet</portlet-class>
<supports>
<mime-type>text/html</mime-type>
</supports>
<portlet-info>
<title>My Portlet</title>
</portlet-info>
<portlet-preferences>
<preference>
<name>ViewPage</name>
<value>/WEB-INF/templates/myportlet/view.ftl</value>
</preference>
</portlet-preferences>
</portlet>