Login required
Download

Portlets Plugin

(2)
Author(s): Kenji Nakamura & Lee Butts
Current Release: 0.7
Grails Version: 1.1 > *
Tags jsr-168
This plugin is designed as an "abstracted" plugin, and shouldn't be installed as a stand-alone. See portlets-liferay and portlets-pluto for the installation.

Portlets Plugin

Please create an issue in JIRA under the Grails-Portlets component if you find problems or come up with ideas for enhancements.

Overview

This plugin aims to provide a simple (grails) way of developing JSR-168 portlets using well known Grails conventions that can be deployed to compliant Portal servers. Currently Liferay 5.2 and Pluto 1.1.7 are supported.

JSR-286 will be supported once springframework bundled with Grails is upgraded to 3.0. spring-mvc-portlet 2.5.6 doesn't support JSR-286.

Portlets plugin consists of "grails-portlets-plugin" generating JSR-168 compliant configuration files, "grails-portlets-liferay" for Liferay specific configurations, "grails-portlets-pluto" for Pluto specific configuration, "grails-pluto", which adds pluto runtime to grails and launch the container with "run-app" command, and "grails-liferay-exploded", allowing a dynamic reloading of classes and GSPs on a stand-alone Liferay server.

"grails-portlets-plugin" doesn't provide a container specific support so it won't work unless implementation specific plugin such as "grails-portlets-liferay" or "grails-portlets-pluto" is installed. "Portlets" plugin is automatically installed by installing those plugins.

You can generate container specific portlet war file by installing "portlets-liferay" or "portlets-pluto". "liferay-exploded" or "pluto" allows to test with those portal container from grails environment.

Installation

Portlets plugin should be implicitly installed by installing a container specific portlets plugin.

Liferay portlets

Please see portlets-liferay and liferay-exploded for the details.
export LIFERAY_HOME=/your_path_to/liferay-portlet-5.2.2
grails install-plugin portlets-liferay
grails install-plugin liferay-exploded

Pluto portlets

Please see portlets-pluto and pluto for the details.
grails install-plugin portlets-pluto  
grails install-plugin pluto

Create a portlet

grails create-portlet MyFirst

The command generates a portlet file "grails-app/portlets/MyFirstPortlet.groovy" as following.

import javax.portlet.*

class MyFirstPortlet {

def title = 'Portlet Title' def description = ''' Description about the portlet goes here. ''' def displayName = 'Display Name' def supports = ['text/html':['view', 'edit', 'help']]

// Liferay server specific configurations def liferay_display_category = 'MyCategory'

def actionEdit = { //TODO Define action phase portletResponse.setPortletMode(PortletMode.VIEW) }

def renderEdit = { //TODO Define render phase. Return the map of the variables bound to the view ['mykey':'myvalue'] }

def actionView = { //TODO Define action phase }

def renderView = { //TODO Define render phase. Return the map of the variables bound to the view ['mykey':'myvalue'] }

def actionHelp = { //TODO Define action phase portletResponse.setPortletMode(PortletMode.VIEW) }

def renderHelp = { //TODO Define render phase. Return the map of the variables bound to the view ['mykey':'myvalue'] } }

"actionXXX" is invoked when a form is submitted, and "renderXXX" is invoked when the page is rendered.

The following variables are bound to the portlet class.

To generate views, run the following command.

grails generate-portlet-views MyFirst

It generates edit.gsp, help.gsp, and view.gsp under "grails-app/views/myfirst" directory. View.gsp looks like this. Please note portletRequest and portletResponse are bound to the GSP.

<%@ taglib uri="http://java.sun.com/portlet" prefix="portlet" %>
<div>
<h1>View Page</h1>
The map returned by renderView is passed in. Value of mykey: ${mykey}
<form action="${portletResponse.createActionURL()}">
    <input type="submit" value="Submit"/>
</form>
</div>

Deploy to container

You can generate portlet war file just same as a servlet war file.

grails war

Please follow the instruction of the portlet container to deploy the portlet war file.

Pluto

If you install "grails-pluto" plugin, you can run Pluto and deploy the portlet and hot reload the modifications in place. For the details, see Pluto Plugin.

Liferay

If you install "grails-liferay-exploded" plugin, you can deploy an exploded war file to Liferay, and dynamically reload and reflect your changes in the grails project.
  1. Run a deployment command. It generates a war, expand, and copy context.xml
file to Liferay's deploy directory. You can run this command when the server is running or stopped.
grails liferay-deploy
  1. Monitor the console output, and confirm the servlet is successfully
registered.

(liferay1 is the name of a sample portlet war file)
…
21:33:16,176 INFO  [PortletHotDeployListener:219] Registering portlets for liferay1
21:33:18,050 INFO  [PortletHotDeployListener:303] 2 portlets for liferay1 are available for use
...

Once you deploy, you can change the code in the grails projects, and reflect the changes to the running Liferay server by invoking the following command.

grails liferay-update

For the details, please refer to Liferay exploded plugin.

"liferay-exploded" plugin is designed for development purposes only. It utilizes tomcat's hot deployment feature, but due to a memory leak on reloading, you will get OutOfMemoryError after four or five executions of "liferay-update". For production, please deploy the packaged war through Liferay's deploy directory or administration GUI.

Unit Testing

Your portlet groovy classes can be unit tested as per normal Grails controllers.

Functional Testing

The Portlets Plugin includes an embded apache Pluto portlet container (Version 1.1.7) which will be deployed during grails run-app, f you install pluto plugin. Browse to localhost:8080/pluto (login as pluto/pluto). Your portlets will be displayed on the default tab labeled 'Home'. This allows basic functional testing via the WebTest plugin.

Known Issues

TODO

Reference

Configuration

Standard property names are used to generate the portlet.xml information for each portlet. They should be defined at the class level and initialized. e.g.
def title = 'HelloWorld'
def displayName = 'Grails Hello World Portlet'
def supports = ['*/*':['view', 'edit']]

There are portal container specific properties too. Please consult portlets-liferay and portlets-pluto plugins for the details.

Portlet Information

title (mandatory)

the title of the portlet (normally appears in the title bar when the portlet is displayed)

description

a description of the portlet

displayName (mandatory)

the name of the portlet when displayed to the user

shortTitle

a short title for your portlet

keywords

keywords that describe your portlet

Portlet Mode

supports (mandatory)

a map containing mime types and a list containing supported window modes. Standard modes available (According to the spec) are view, edit and help

customModes

a map containing custom window modes and their descriptions. Any custom modes referenced in supports need to be declared here.

Portlet Preferences

supportedPreferences

a map defining the portlet preferences supported by your portlet. The key is the parameter name, the value is the default value for the preference. Multiple values can be supplied as a list and will create a multi-valued portlet preference.

Security

roleRefs

a list or map that specifies the roles required to access this portlet. It is either a list of role names or a map wher the key is the role name and the value is the role link (see the Portlet spec for more details on what how these fields are used). These values are used to generate <security-role-ref> elements.

Custom Window States

customWindowStates

a map containing custom window states used by this portlet and their descriptions

Internationalization

TODO

Action Conventions

Simple case

For simple cases a portlet can define two closures: doAction and doRender which will be called as per the Portlet specification request behaviour e.g. doRender each time a page with the portlet on is rendered and doAction when a form inside the portlet posts to the actionURL.

Portlet mode based action

action and render closures with portlet mode as a prefix (e.g. actionView, renderView) are invoked.

parameter based action

It hasn't been tested. You can inspect a request parameter in portlet mode based action, and dispatch based on the value as an interim solution.

actionView = {
    if(portletRequest.getParameter('action') == 'foo') {
        actionFoo()
    }
}

private actionFoo() { … }

View Conventions

The plugin will first look for a view matching the current portlet mode e.g view.gsp, edit.gsp, help.gsp etc. If a view cannot be found it will fallback to render.gsp.

Convenience properties

The following properties are provided for use inside actions to access common objects provided by the Portlet API.

Request/Response

portletRequest

the current PortletRequest. It will be a RenderRequest or an ActionRequest depending on which controller action is executing (a render or an action call).

portletResponse

the current PortletResponse. It will be a RenderResponse or an ActionResponse depending on which controller action is executing (a render or an action call).

request

It is an instance of HttpServletRequest of the underlying portlet container. You should use portletRequest instead of request for normal portlet operations. It is available only when you need to something special with the underlying servlet request and use at your own risk.

response

It is an instance of HttpServletResponse of the underlying portlet container. You should use portletResponse instead of response for normal portlet operations. It is available only when you need to something special with the underlying servlet request and use at your own risk.

Portlet Session

session

the current PortletSession.

Portlet Preferences

preferences

the PortletPreferences object for the current user.

Window State

windowState

the current WindowState.

Portlet Mode

mode

the current PortletMode.

History

0.7 (11/4/09)

  • Got rid of unused Jetty import statements.

0.5 (09/22/09)

  • Added commons-logging-1.1.1.jar to fix the deployment issue on liferay-5.2.3 with tomcat-6 due to listener registration failure.

0.4 (06/30/09)

  • Fixed unbalanced curly bracket in gsp template files.

0.3 (05/28/09)

  • Updated gsp template so that submission works on both pluto and liferay.
  • Added liferay_display_category field to the template so that you can generate
Liferay compatible portlet without any modifications.

0.2 (05/25/09)

Initial release.