Portlets are pluggable user interface software components that are
managed and displayed in a web portal. They produce fragments of markup
code that are aggregated into a portal.
There are two specifications of portlets exist nowadays, they are
JSR-168 (Java Portlet Api) and JSR-286 (Java Portlet Api 2.0).
Related Articles
Liferay is an opensource portal bundled with different servlet containers, such as Tomcat, Jetty, Geronimo, JBoss, etc. As it is opensource it has a reach variaty of opensource portlets for every life situation. To deploy your own one, you need Liferay portal installed. I used Liferay bundled with Tomcat of version 6.1.0 and Grails 2.0.4.
Documentation for Liferay Portal can be found at http://www.liferay.com. However, provided docs are not very good in my opinion.
Let's create our own portlet for Liferay portal. You can create more
than one portlet within your Grails application, what's very good, and
actually it’s very easy to implement portlets in Groovy way, so let's
keep going!
We need two great plugins installed, called portlets and portlets-liferay:
1 2 |
|
Documentation for these plugins also available at Grails site, to which you can refer at any time and place.
To create portlet application we need to generate portlet class which will contain specific Liferay configurations and portlet actions needed for portlet to work. This can be done by executing a Grails command:
1
|
|
* Note that this command will automaticaly add 'Portlet' keyword to the
end of '
You've just created a portlet class, great.
Portlet.groovy file will be generated in /grails-app/portlets directory. Here how it would look like:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
|
Portlets-liferay plugin for Grails reads configuration from Config.groovy and Portlet.groovy files and then generates all needed Liferay xmls and property files in grails-app/web-app/WEB-INF directory.
In your portlet class you can define title of portlet, display name,
description of this portlet, header JavaScript and CSS files references,
etc.
In Config.groovy file you can specify role-mapper and custom user
attributes, like I did:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
Available Liferay roles can be found at "Control panel → Roles".
Freshly generated portlet class has some demonstrating closures that render demo views, but we don't have any views yet. Ok, let's generate some of them:
1
|
|
Aha, here they are, thank you Grails! "view.gsp, edit.gsp, help.gsp"
would be created in directory /grails-app/views/
After these steps your portlet can be deployed to portal. Hmm, but it's not just what we wanted as it does nothing at the moment, so let's add some stuff to out portlet.
I would like to create a domain class with the name Car:
1
|
|
Now simply add two string fields to this class: 'name' and 'color':
1 2 3 4 5 |
|
BootStrap class can be used to fill database with values as usual:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
Generated portlet class has renderView and actionView actions, as you can see the second part of action's name is 'VIEW', it means that these actions refer to 'VIEW' portlet's mode. Also there are 'EDIT' and 'HELP' portlet modes available. More information about portlet actions available at liferay community site, please refer to it if you got some questions (and may also Google be with you).
renderView - renders view.gsp.
renderAction - makes some stuff for the VIEW mode. Let's change these two actions, so that portlet would be able to delete car instances from database:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
|
We also need to change 'view.gsp' file, to meet our desires.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
But what should you do if you wish to add your own action? Hmm... that is the question! Let's define an action for creating cars. In our portlet class it will look like this:
1 2 3 4 5 6 7 8 9 10 11 |
|
By the moment of writing this article GORM didn't work in portlet actions, and this is the known bug. The simplest way to solve this problem is creating a service class which would do GORM work. Yeah, here it is:
1 2 3 4 5 6 |
|
OK, we solved our GORM trouble, now let's create view for adding cars. We need to get link to action from view, so let's change view.gsp, it's pretty simple:
1 2 3 4 5 6 7 8 9 10 |
|
'' tag creates portlet's actionURL, we need to specify a parameter which would be the name of portlet's action. I created action 'addCar', so I need to specify parameter for actionURL with value of 'addCar'. After doing this, you will be able to add cars to database.
We can invoke our newly created portlet action, but now another question is: 'How can we render our own views?' Well, it is not much different from mapping to portlet action, you simply have to define portlet tag in gsp.
When car is added I want my application to show a message that car was added. For that case I created 'added.gsp' in /views/car/ directory, which looks like that:
1 2 3 4 5 6 7 8 |
|
I wish this page to be rendered after car was added, so I need to change our 'addCar' closure a little:
1 2 3 4 5 6 7 8 9 10 11 |
|
'portletResponse.setRendererParameter' will invoke portlet's closure named 'renderAdded' which I left empty, as it's not necessary to get any model for that view:
1 2 3 |
|
Also If you wish to render custom gsp view file, you can do it by creating a link to action which renders gsp page:
1 2 3 4 5 6 7 |
|
By clicking on "Go to page" renderAdded will be invoked, and that action renders 'added.gsp'. Just what we needed! :)
And this is it! Now let's see what we've got:
Create war file, using Grails command:
1
grails war
Then just copy freshly created war file to %LIFERAY_HOME%/deploy directory. Liferay will deploy your portlet application, and it would be available for use.
Add portlet to the page. Login as Bruno admin (or another credentials with admin rights), then in control panel go to Add → More →
(in our case it’s named 'Cars') and simply drag and drop ' ' (which is 'Car Portlet' for me) to the page.
Here's a screenshot:
GitHub: repo link
Hope, this will be helpful. Cheers!
This post first appeared on Programming | SysGears - Custom Software, please read the originial post: here