Monday, February 24, 2014

Recycle Bin for your Custom Portlet in Liferay 6.2

Now It's almost around 4 months since Liferay 6.2 is released with complete makeover and including many power packs like Responsive Design using Bootstrap, Mobile friendly support, WCM improvements, ADT(Application Display Template), Recycle Bin & others. For more details visit What's new in Liferay 6.2.

Among all of these today I would like to talk about Recycle Bin in Liferay 6.2 & how you can plug it with your Custom portlet.

Recycle Bin

Think of a situation where you are working on Production site and while deleting multiple content you've also deleted a content which is being used on a Site Home page !! Now you don't have way to quickly revert your delete action and restore deleted content.

Now going forward from Liferay 6.2, No need to worry about such circumstances as you'll have a option to restore accidentally deleted content using Recycle Bin feature. It's been added for all important Liferay asset types.

  • Blogs
  • Bookmarks
  • Documents and Media
  • Message Boards (and attachments)
  • Web Content
  • Wiki (and attachments)

But what if you want Recycle Bin for your Custom Portlet which is as important as other Liferay assets. Well Good News is, Liferay has made this in generalize way so that it can be used with custom portlet as well.

Recycle Bin can be configured from Site Configuration. You can turn on/off Recycle Bin and also change the Max Age(in number of days) for content being kept in Recycle Bin for specific Site.
Recycle Bin Configuration
Recycle Bin Configuration

And we can get all the content that is moved to Recycle Bin from Site Administration - Content - Recycle Bin.
Recycle Bin in Site Administration
Recycle Bin in Site Administration

So far we've seen how it will be useful and how to configure it to be able to use it with Liferay OOTB assets. But what if you want this feature for your custom asset(portlet) ?

Well today I'm going to share the steps that I've followed and be able to add Recycle Bin for a Custom Portlet.

Sample Recycle Bin Portlet

Here for reference I'm using a Simple Service Builder Portlet which does CRUD operation (add/update/delete records from Database). Here I am not going in deep on how to create Service Builder portlet.
Below is the service.xml for the same.
Add Event - Sample Recycle Bin
Add Event
View Events with Delete Action
View Events with Delete Action
Now we'll replace "Delete" with "Move to Recycle Bin" by plug Recycle Bin capabilities in this portlet.

Service.xml Changes

First we are going to make changes in service.xml

Enable Trash
We need to add "trash-enabled="true" in order to tell service builder that particular entity will be using Trash(Recycle Bin).
Build service after enabling trash for a entity. Service builder will auto generate some methods for entity model which will be later required.

Add Status Columns
Next we need to add columns required by Trash in order to maintain the logs of events occurred while moving assets from/to Trash.

Adding some finders in service.xml.

We also need to add TrashEntry reference.
Build service after this changes in service.xml

Trash Handler

Next we need to add trash-handler & asset-renderer-factory in liferay-portlet.xml. Here I've added com.opensourceforlife.portlet.samplerecyclebin.EventTrashHandler as a trash-handler & com.opensourceforlife.portlet.samplerecyclebin.EventAssetRendererFactory as asset-renderer-factory.

Create a class EventTrashHandler which extends BaseTrashHandler and override it's unimplemented methods. Complete class can be found here.
public class EventTrashHandler extends BaseTrashHandler
Create EventAssetRendererFactory extends BaseAssetRendererFactory and override it's unimplemented methods. Complete class can be found here.
public class EventAssetRendererFactory extends BaseAssetRendererFactory
We also need to create EventAssetRenderer which is being used by EventAssetRendererFactory.

Change Delete Action

Now we are going to replace "Delete" button to "Move to Recycle Bin" in actions. For this we'll need to change Delete action in jsp.
Here first we are passing Command be either 'delete'or 'move_to_trash'. So if Recycle Bin is enabled for a particular Site it will pass 'move_to_trash' else 'delete' as usual.
Next we've changed icon based on the command which will be available. As shown we've a attribute 'trash' which will be true if Recycle Bin is enabled for a site and respectively it will change UI for a particular event.

Deploy your portlet after these changes and you'll see "Move to Recycle Bin" option if Recycle Bin is enabled for your site.
Recycle Bin action for a Event
'Move to Recycle Bin' action for a Event
Upon clicking on 'Move to Recycle Bin' will not work as expected yet. As still we'll have to write a logic for moving event to Recycle Bin and option to restore it back.

Controller Changes

Let's changes deleteEvent in our controller so that based on command(delete or move_to_trash) we'll get in controller, we can perform respective actions.

For 'delete' command we'll perform normal delete action but for 'move_to_trash' we'll be executing EventLocalServiceUtil.moveEntryToTrash(userId, eventId). That we need to implement in and we'll see that in next steps.

Service Implementation Changes

Next we need to make changes in Event Service Implementation to leverage trash logic mainly for moving event to Trash and restoring it back from Trash. Here you'll need to take extra care if you are Indexing your data in lucene OR you've workflow enabled for your plugins portlet.

Here we will write a logic to move Event to Trash. This we'll call when user will click on 'Move to Recycle Bin' option from Event actions.

As name suggest, it will take care of restoring Event back from Trash to Event portlet.
When any move anything to Trash we can either Restore it or Permanently Delete it.
Recycle Bin Options
Recycle Bin Options
So we'll add a logic to remove entry from trash upon actually deleting a Event either directly from Event(when Recycle Bin is not enabled) or from Recycle Bin.
We'll need to change logic which is fetching List of events to not include events already moved to trash. It uses finder method that we've created earlier by adding finders in service.xml

Trash Handler Changes

Finally we'll make changes in EventTrashHandler that we've created earlier. And will change restoreTrashEntry & deleteTrashEntry methods. Here deleteTrashEntry will make actual call to Delete Event and restoreTrashEntry will call method 'restoreEntryFromTrash' from EventLocalServiceUtil that we've implemented in EventLocalServiceImpl.

That's it !! Just deploy your portlet and you are done with Recycle Bin plugged in for your Custom Portlet.
Hope this is helpful if you would like to have Recycle Bin for your plugins portlet.


Packaged War
Packaged war ready to use can be download here(sample-recycle-bin-portlet-*.war).

Source Code
Source code can be download OR fork Sample Recycle Bin Git Repository.

Feel free to provide your valuable feedback. You can reach out to me at admin{at} for any query/issue.

Best Regards,
Tejas Kanani
Senior Consultant @ CIGNEX Datamatics

Saturday, January 11, 2014

Custom Landing Page Hook v1.2.1 is now Liferay 6.2 CE/EE Compatible

Hi All,

You might already have heard about Liferay's latest version release, Liferay 6.2 CE GA1 with power packs and lots of enhancements. For EE customer, Liferay 6.2.10 EE GA1 is also released and available to download from Customer Portal.
With 6.2 release Liferay has come up with a major look & feel changes by introducing Bootstrap & Alloy UI 2. For more details you can go through my recent blog on What is new in Liferay 6.2.

Moving forward with the latest Liferay 6.2 version, I am pleased to share that Liferay Marketplace App Contest winner "Custom Landing Page Hook" is now ready to be use with Liferay 6.2 CE GA1+ & Liferay 6.2.10 EE GA1+. For further details on what's new in this and how to use this hook, visit Readme from Git Repository.


Packaged War - Liferay Marketplace OR Github Repository Release.
Source code - Git Repository

Thanks & Best Wishes,
Tejas Kanani
Senior Consultant @ CIGNEX DATAMATICS

Saturday, October 19, 2013

Custom Landing Page Hook v1.1 Released !!!

I am pleased to share that Custom Landing Page Hook v1.1 is released in Liferay Marketplace. It has come up with some new options as well as few bug fixes.

New Feature !! 

There is a new option added by which any specific page within a Site/Organization can be made a landing page for that Site/Organization instead of their home page.
Just create a custom attribute of Site/Organization by mentioning the page friendlyURL.

For defining,
1) Site/Organization's Public page
- Create custom attribute of type "TextField" with key "landingPagePublic" and define value as desired page's friendlyURL. i.e. /welcome
2) Site/Organization's Private page
- Create custom attribute of type "TextField" with key "landingPagePrivate" and define value as desired page's friendlyURL. i.e. /myhome

Define specific landing page for site/organization via Custom Attribute in Custom Landing Page Hook


Now It's also compatible with recent release of Liferay.
  • 6.1.2 CE GA3
  • 6.1.30 EE GA3

Glassfish issue with PACL workaround

There is an open PACL/Glassfish issue which is currently under investigation (
Until it will get fixed below is the workaround for glassfish users.
1. Start Glassfish with security manager
2. Make sure is set to "liferay" in

Latest Changes

You'll find the latest source code for Custom Landing Page Hook from Git Repository. You can also download the latest packaged war from here (v1.2). This will also include the changes that have been made post v1.1 release of Liferay Marketplace App submission.

For any Issue/Support

For any issue/support, you can either reach out to me at Or you can create a issue in Github issues

Tejas Kanani
Senior Consultant @ CIGNEX Datamatics