Monday, May 25, 2015

Liferay ADT Implementation for Custom Portlet

Liferay Application Display Templates (ADT) is great way to change Portlet view dynamically without changing JSP pages code.

Liferay ADT use the Free Marker/Velocity Templates to change Portlet view dynamically and this can be done by Liferay administrator from Site Administration.

By Default Liferay have given ADT capability for few Portlets which are in Liferay portal and we can change Portlets views dynamically by using velocity/free marker templates.

Follow below Article Know about ADT



Liferay have given ADT API to implement ADT support for Out of Box Portlet that is Custom Portlets.

Generally what are the variables or elements which required in view logic we will group it and will be stored in template engine and whenever we need in views we simply use reference names to access the variables or elements from template engine and all these mechanism was implemented in Liferay ADT API so that we can implement ADT Support to custom Portlets.

Liferay Have Template Handler which will take care of the groping variables and store into template engine and at the time of render we will use reference variable to access data from template engine and these template engine are velocity or free marker that is why we will use velocity/free marker templates in the ADT to change Portlet display dynamically.

Implementation ADT Support to Custom Portlet
  1. Create Liferay MVC Portlet
  2. Implement Portlet Display Template Handler Java Class
  3. Register Portlet Display Template Handler Java Class
  4. Implement ADD_PORTLET_DISPLAY_TEMPLATE Permission to Custom Portlet
  5. Implement Configuration View to Portlet
  6. Implement View Logic to Read Configured Templates

Create Liferay MVC Portlet

Creating Liferay MVC Portlet is very straight forward step and you can use Liferay IDE to create Liferay MVC Portlet.


Implement Portlet Display Template Handler Java Class

To handle template variables we will use Portlet Display Template Handler java class from ADT API and it will take care the template variables which are required in the portlet display and these variables we will defined in the Portlet Display Template Handler class.

We need to implement Custom Portlet Display Template Handler class that should extend the BasePortletDisplayTemplateHandler.

BasePortletDisplayTemplateHandler java class consist many methods so we will override some of the methods in the Custom Portlet Display Template Handler class

The following are methods

getClassName(): This will defined what type of entries you are rendering  and typically its model class name(Student.class, Employee.class)

getName(): Declares the name of your ADT type (typically, the name of the portlet).

getResourceName(): Specifies which resource is using the ADT (e.g. a portlet) for permission checking.

 getTemplateVariableGroups(): Defines the variables exposed in the template editor.

The following is Example Implementation


public class ADTPOCPortletDisplayTemplateHandler extends
BasePortletDisplayTemplateHandler {

@Override
public String getClassName() {
// TODO Auto-generated method stub
return Student.class.getName();
}

@Override
public String getName(Locale arg0) {
// TODO Auto-generated method stub
return "ADTPOC Template";
}

@Override
public String getResourceName() {
// TODO Auto-generated method stub
return "ADTPOC_WAR_ADTPOCportlet";
}

public Map<String, TemplateVariableGroup> getTemplateVariableGroups(
long classPK, String language, Locale locale)
throws Exception {

Map<String, TemplateVariableGroup> templateVariableGroups =
super.getTemplateVariableGroups(classPK, language, locale);

TemplateVariableGroup templateVariableGroup =
templateVariableGroups.get("fields");

templateVariableGroup.empty();

templateVariableGroup.addCollectionVariable(
"students", List.class, PortletDisplayTemplateConstants.ENTRIES,
"student", Student.class, "curStudent", "name");
return templateVariableGroups;
}
}


Register Portlet Display Template Handler Java Class

We already implemented Custom Register Portlet Display Template Handler Java ClassAnd now we need to register this class name so that Portlet will get ADT Capability to do this we will use Liferay-portlet.xml file configuration file where we need to configure Custom Portlet Display Template Handler Java Class and <template-handler/> is tag which should be enclosed by <portlet/>

The following is example Configuration


<portlet>
<portlet-name>ADTPOC</portlet-name>
<icon>/icon.png</icon>
<configuration-action-class>com.adt.poc.config.ADTPOCConfigImpl</configuration-action-class>
<template-handler>com.adt.poc.template.ADTPOCPortletDisplayTemplateHandler
</template-handler>

<header-portlet-css>/css/main.css</header-portlet-css>
<footer-portlet-javascript>/js/main.js</footer-portlet-javascript>
<css-class-wrapper>ADTPOC-portlet</css-class-wrapper>
</portlet>

Implement “ADD_PORTLET_DISPLAY_TEMPLATE” Permission to Custom Portlet

Since the ability to add ADTs is new to your portlet, we need to configure permissions so that administrative users can grant permissions to the roles that will be allowed to create and manage display templates. Just add the action key ADD_PORTLET_DISPLAY_TEMPLATE to your portlet’s docroot/WEB-INF/src/resource-actions/default.xml file


<?xml version="1.0"?>
<!DOCTYPE resource-action-mapping
PUBLIC "-//Liferay//DTD Resource Action Mapping 6.2.0//EN" "http://www.liferay.com/dtd/liferay-resource-action-mapping_6_2_0.dtd">
<resource-action-mapping>
<portlet-resource>
<portlet-name>ADTPOC</portlet-name>
<permissions>
<supports>
<action-key>ADD_PORTLET_DISPLAY_TEMPLATE</action-key>
<action-key>ADD_TO_PAGE</action-key>
<action-key>CONFIGURATION</action-key>
<action-key>VIEW</action-key>
</supports>
<site-member-defaults>
<action-key>VIEW</action-key>
</site-member-defaults>
<guest-defaults>
<action-key>VIEW</action-key>
</guest-defaults>
<guest-unsupported>
<action-key>CONFIGURATION</action-key>
</guest-unsupported>
</permissions>
</portlet-resource>
</resource-action-mapping>


Implement Configuration View to Portlet

To provide ADT Templet editor to create new ADT templates will use Liferay Configuration page where we will provide template editor code so that when we add new templates to Portlet, where you can  see all  defined variables.

Follow the Article to Implement Portlet Configuration


Now Portlet configuration page(config.jsp) we need to add following code so that it will provide template editor while design templates and these can be accessed through Portlet configuration option by administrator.< liferay-ui:ddm-template-selector/>  is tag which will take care all.

The following is example code in config.jsp page


<%@page import="com.liferay.portal.kernel.util.Constants"%>
<%@page import="com.liferay.portal.util.PortalUtil"%>
<%@ include file="init.jsp" %>
<%@page import="com.adt.poc.model.Student"%>
<%@page import="com.liferay.portal.kernel.template.TemplateHandlerRegistryUtil"%>
<%@page import="com.liferay.portal.kernel.template.TemplateHandler"%>
<liferay-portlet:actionURL portletConfiguration="true" var="configurationURL" />
<aui:form action="<%= configurationURL %>" method="post" name="fm">
<aui:input name="<%= Constants.CMD %>" type="hidden" value="<%= Constants.UPDATE %>" />
<aui:fieldset>
<div class="display-template">
<%
TemplateHandler templateHandler = TemplateHandlerRegistryUtil.getTemplateHandler(Student.class.getName());
%>
<liferay-ui:ddm-template-selector
classNameId="<%= PortalUtil.getClassNameId(templateHandler.getClassName()) %>"
displayStyle="<%= displayStyle %>"
displayStyleGroupId="<%= displayStyleGroupId %>"
refreshURL="<%= PortalUtil.getCurrentURL(request) %>"
showEmptyOption="<%= true %>"
/>
</div>
</aui:fieldset>
<aui:button type="submit" name="submit"></aui:button>
</aui:form>


Implement View Logic to Render Configured Templates

Now we need to provide logic that will render configure templates to change Portlet view and this we will write in default view page of Portlet.

When the ADT template is configures to Portlet then it will render the configured template otherwise it will render default view.

The following is sample code.


<%@page import="java.util.ArrayList"%>
<%@page import="com.adt.poc.model.Student"%>
<%@page import="java.util.List"%>
<%@ include file="init.jsp" %>

This is the <b>Location Listing Portlet</b> in View mode.
<%
List<Student> students = new ArrayList<Student>();
for(int i=1; i<10; i++){
Student student = new Student();
student.setId(i);
student.setName("name"+i);
student.setCity("city"+i);
students.add(student);
}
%>
<%=portletDisplayDDMTemplateId%>
<c:choose>
<c:when test="<%= portletDisplayDDMTemplateId > 0 %>">
<%= PortletDisplayTemplateUtil.renderDDMTemplate(pageContext, portletDisplayDDMTemplateId, students) %>
</c:when>
<c:otherwise>
<table border="1">
<tr><th>Name</th><th>city</th></tr>

<%
for(Student student:students){%>
<tr><td><%=student.getName()%></td>
<td><%=student.getCity()%></td></tr>
<%} %>
</table>
</c:otherwise>
</c:choose>


Download ADT Implemented Custom Portlet


ADT Implementation in Custom Portlet Complete Example

In the example used Dummy Model class Student.java and while create Student object simply use for loop to create student object and these will be available as entries in the templates at the time of create new templates for Portlet display.

ADTPOCPortletDisplayTemplateHandler.java


package com.adt.poc.template;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import com.adt.poc.model.Student;
import com.liferay.portal.kernel.language.LanguageUtil;
import com.liferay.portal.kernel.portletdisplaytemplate.
BasePortletDisplayTemplateHandler;
import com.liferay.portal.kernel.template.TemplateVariableGroup;
import com.liferay.portal.kernel.util.StringPool;
import com.liferay.portlet.portletdisplaytemplate.util.
PortletDisplayTemplateConstants;
public class ADTPOCPortletDisplayTemplateHandler extends
BasePortletDisplayTemplateHandler {

@Override
public String getClassName() {
// TODO Auto-generated method stub
return Student.class.getName();
}

@Override
public String getName(Locale arg0) {
// TODO Auto-generated method stub
return "ADTPOC Template";
}

@Override
public String getResourceName() {
// TODO Auto-generated method stub
return "ADTPOC_WAR_ADTPOCportlet";
}

public Map<String, TemplateVariableGroup> getTemplateVariableGroups(
long classPK, String language, Locale locale)
throws Exception {

Map<String, TemplateVariableGroup> templateVariableGroups =
super.getTemplateVariableGroups(classPK, language, locale);

TemplateVariableGroup templateVariableGroup =
templateVariableGroups.get("fields");

templateVariableGroup.empty();

templateVariableGroup.addCollectionVariable(
"students", List.class, PortletDisplayTemplateConstants.ENTRIES,
"student", Student.class, "curStudent", "name");
return templateVariableGroups;
}
}


liferay-portlet.xml (/ADTPOC-portlet/docroot/WEB-INF/liferay-portlet.xml)


<?xml version="1.0"?>
<!DOCTYPE liferay-portlet-app
PUBLIC "-//Liferay//DTD Portlet Application 6.2.0//EN" "http://www.liferay.com/dtd/liferay-portlet-app_6_2_0.dtd">

<liferay-portlet-app>
<portlet>
<portlet-name>ADTPOC</portlet-name>
<icon>/icon.png</icon>
<configuration-action-class>com.adt.poc.config.ADTPOCConfigImpl</configuration-action-class>
<template-handler>com.adt.poc.template.ADTPOCPortletDisplayTemplateHandler
</template-handler>

<header-portlet-css>/css/main.css</header-portlet-css>
<footer-portlet-javascript>/js/main.js</footer-portlet-javascript>
<css-class-wrapper>ADTPOC-portlet</css-class-wrapper>
</portlet>
<role-mapper>
<role-name>administrator</role-name>
<role-link>Administrator</role-link>
</role-mapper>
<role-mapper>
<role-name>guest</role-name>
<role-link>Guest</role-link>
</role-mapper>
<role-mapper>
<role-name>power-user</role-name>
<role-link>Power User</role-link>
</role-mapper>
<role-mapper>
<role-name>user</role-name>
<role-link>User</role-link>
</role-mapper>
</liferay-portlet-app>


default.xml (docroot/WEB-INF/src/resource-actions/default.xml)


<?xml version="1.0"?>
<!DOCTYPE resource-action-mapping
PUBLIC "-//Liferay//DTD Resource Action Mapping 6.2.0//EN" "http://www.liferay.com/dtd/liferay-resource-action-mapping_6_2_0.dtd">
<resource-action-mapping>
<portlet-resource>
<portlet-name>ADTPOC</portlet-name>
<permissions>
<supports>
<action-key>ADD_PORTLET_DISPLAY_TEMPLATE</action-key>
<action-key>ADD_TO_PAGE</action-key>
<action-key>CONFIGURATION</action-key>
<action-key>VIEW</action-key>
</supports>
<site-member-defaults>
<action-key>VIEW</action-key>
</site-member-defaults>
<guest-defaults>
<action-key>VIEW</action-key>
</guest-defaults>
<guest-unsupported>
<action-key>CONFIGURATION</action-key>
</guest-unsupported>
</permissions>
</portlet-resource>
</resource-action-mapping>



config.jsp (/docroot/config.jsp)


<%@page import="com.liferay.portal.kernel.util.Constants"%>
<%@page import="com.liferay.portal.util.PortalUtil"%>
<%@ include file="init.jsp" %>
<%@page import="com.adt.poc.model.Student"%>
<%@page import="com.liferay.portal.kernel.template.TemplateHandlerRegistryUtil"%>
<%@page import="com.liferay.portal.kernel.template.TemplateHandler"%>
<liferay-portlet:actionURL portletConfiguration="true" var="configurationURL" />
<aui:form action="<%= configurationURL %>" method="post" name="fm">
<aui:input name="<%= Constants.CMD %>" type="hidden" value="<%= Constants.UPDATE %>" />

<aui:fieldset>
<div class="display-template">

<%
TemplateHandler templateHandler = TemplateHandlerRegistryUtil.getTemplateHandler(Student.class.getName());
%>

<liferay-ui:ddm-template-selector
classNameId="<%= PortalUtil.getClassNameId(templateHandler.getClassName()) %>"
displayStyle="<%= displayStyle %>"
displayStyleGroupId="<%= displayStyleGroupId %>"
refreshURL="<%= PortalUtil.getCurrentURL(request) %>"
showEmptyOption="<%= true %>"
/>
</div>
</aui:fieldset>
<aui:button type="submit" name="submit"></aui:button>
</aui:form>


ADTPOCConfigImpl.java (src/com/adt/poc/config/ADTPOCConfigImpl.java)


package com.adt.poc.config;
import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.PortletConfig;
import com.liferay.portal.kernel.portlet.DefaultConfigurationAction;
import com.liferay.portal.kernel.util.ParamUtil;
import com.liferay.portlet.PortletPreferencesFactoryUtil;

public class ADTPOCConfigImpl extends DefaultConfigurationAction {
@Override
public void processAction(PortletConfig portletConfig,
ActionRequest actionRequest, ActionResponse actionResponse)
throws Exception {
// TODO Auto-generated method stub
String portletResource = ParamUtil.getString(actionRequest, "portletResource");
javax.portlet.PortletPreferences prefs = PortletPreferencesFactoryUtil.getPortletSetup(actionRequest, portletResource);
String displayStyle = ParamUtil.getString(actionRequest, "displayStyle");
prefs.setValue("displayStyle", displayStyle);
prefs.store();
super.processAction(portletConfig, actionRequest, actionResponse);
}
}


view.jsp(docroot/view.jsp)


<%@page import="java.util.ArrayList"%>
<%@page import="com.adt.poc.model.Student"%>
<%@page import="java.util.List"%>
<%@ include file="init.jsp" %>

This is the <b>Location Listing Portlet</b> in View mode.
<%
List<Student> students = new ArrayList<Student>();
for(int i=1; i<10; i++){
Student student = new Student();
student.setId(i);
student.setName("name"+i);
student.setCity("city"+i);
students.add(student);
}
%>
<%=portletDisplayDDMTemplateId%>
<c:choose>
<c:when test="<%= portletDisplayDDMTemplateId > 0 %>">
<%= PortletDisplayTemplateUtil.renderDDMTemplate(pageContext, portletDisplayDDMTemplateId, students) %>
</c:when>
<c:otherwise>
<table border="1">
<tr><th>Name</th><th>city</th></tr>

<%
for(Student student:students){%>
<tr><td><%=student.getName()%></td>
<td><%=student.getCity()%></td></tr>
<%} %>
</table>
</c:otherwise>
</c:choose>


init.jsp (docroot/init.jsp)


<%@page import="com.liferay.portal.kernel.util.StringPool"%>
<%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://liferay.com/tld/aui" prefix="aui" %>
<%@taglib uri="http://liferay.com/tld/portlet" prefix="liferay-portlet" %>
<%@taglib uri="http://liferay.com/tld/security" prefix="liferay-security" %>
<%@taglib uri="http://liferay.com/tld/theme" prefix="liferay-theme" %><%@
taglib uri="http://liferay.com/tld/ui" prefix="liferay-ui" %>
<%@taglib uri="http://liferay.com/tld/util" prefix="liferay-util" %>
<%@page import="com.liferay.portlet.portletdisplaytemplate.util.
PortletDisplayTemplateUtil"%>
<%@page import="com.liferay.portal.kernel.util.GetterUtil"%>

<portlet:defineObjects />

<liferay-theme:defineObjects />
<%
String displayStyle = 
 GetterUtil.getString(portletPreferences.getValue("displayStyle", StringPool.BLANK));
long displayStyleGroupId = GetterUtil.getLong(portletPreferences.getValue("displayStyleGroupId", null), scopeGroupId);

long portletDisplayDDMTemplateId = PortletDisplayTemplateUtil.getPortletDisplayTemplateDDMTemplateId
(displayStyleGroupId, displayStyle);

boolean showLocationAddress_view = GetterUtil.getBoolean(portletPreferences.getValue("showLocationAddress", StringPool.TRUE));
%>


Usage of Portlet

Deploy Portlet into you portal server

After successful deployment you can see the Portlet in sample category

Login as Admin and Drag and Drop Portlet in the page

The following is Default view of Portlet


Now go to Docbar Admin tab and click on Site Configuration


Configuration section you can see Application Display Templates click on it


Now you can Add new ADT for our Custom Portlet by Select Custom Portlet from Add Button Icon and Select Our Custom Portlet


Once we click on Add then it will launch Template Editor there we need to design New Display to Custom Portlet By using Free Marker/Velocity Templates. Once you design view then click on save then new ADT Template will be created for Custom Portlet



 Now go to Portlet Configuration


In Setup tab you can see Display Template Drop down there you can select our newly created Custom Portlet ADT then save it.



Once you apply new ADT then Portlet Display will be changed such way you can create many Displays to custom Portlet using ADT.

Author

Tuesday, May 12, 2015

Working with Free Marker Templates in Liferay ADT

ADT is great way in Liferay to change the Portlet Display  and we can develop our custom view to the Portlet so that we can change entire look and feel of Portlets without changing the JSP pages.

Go through the Article for More about Liferay ADT


When we are working with ADT we can use Free Marker Templates to change view of Portlet.
This article will give all basics of how to use Free Marker Templates in Liferay ADT.

Some time each Portlet ADT will contain default variables which we can see in the FTL Editor which you can see left side section.




FTL Code Snippets when we work with Liferay ADT

Statement


<#        />


Comment


<#--  This is comment -->


Variable Declaration and Assignment


<#assign name ="meera"/>

<#assign categoryId =100/>


Array Declaration



<#assign cat = [100,101,102] />
 
<#assign selectVocab = ["Department", "Client Scope"] />


Global Variable and Assignment


<#global categoryId =100/>


Print or Output Data


${ name }


IF Statement


<#if categoryId != 0>

<#--  Do something -->

</#if>


If and Else


<#if categoryId != 0>

<#--  Do something -->

<#else>

<#--  Do something -->

</#if>


For Loop


<#assign categoryIds ={13,39,45,10}/>

<#list categoryIds as categoryId>

</#list>


Find something in the object or list


<#if categoryIds?has_content>
           
</#if>


Example loop


<#assign categoryIds ={13,39,45,10}/>
<#if categoryIds?has_content>   
<#list categoryIds as categoryId>
${ categoryId }
</#list>
</#if>


Liferay Tag libraries Import


<#assign aui = taglibLiferayHash["/WEB-INF/tld/aui.tld"] />
<#assign liferay_portlet = taglibLiferayHash["/WEB-INF/tld/liferay-portlet.tld"] />
<#assign liferay_ui = taglibLiferayHash["/WEB-INF/tld/liferay-ui.tld"] />


Create URLs using Tag Libraries


<@liferay_portlet.renderURL var="filterByCategory" windowState="normal">
<@liferay_portlet.param name="mycategoryId" value="100" />
</@liferay_portlet.renderURL>

OR

<@liferay_portlet["renderURL"] var="filterByCategory" windowState="normal">
<@liferay_portlet["param"] name="mycategoryId" value="100" />
</@liferay_portlet["renderURL"]>


Form Elements and From


<@aui.form action="${filterByCategory}" method="post" name="filterForm">
<@aui.input name="categoryName" id="categoryName" type="text" value="" label="Category Name" placeholder="/>
<@aui.select name="mycategoryId" id="mycategoryId" label="Category">
<@aui.option label="Sports" value="100" first="true" />
<@aui.option label="Games" value="101"/>
</@aui.select>
<@aui.button type="submit" value="Submit"></@aui.button>
</@aui.form>

OR

<@aui["form"] action="${filterByCategory}" method="post" name="filterForm">
<@aui["input"] name="categoryName" id="categoryName" type="text" value="" label="Category Name" placeholder="/>
<@aui["select"] name="mycategoryId" id="mycategoryId" label="Category">
<@aui["option"] label="Sports" value="100" first="true" />
<@aui["option"] label="Games" value="101"/>
</@aui["select"]>
<@aui["button"] type="submit" value="Submit"></@aui["button"]>
</@aui["form"]>


Load Static OR Util Class


<#assign ParamUtil = staticUtil["com.liferay.portal.kernel.util.ParamUtil"]/>
<#assign categoryId =ParamUtil.getLong(request,"mycategoryId")/>
${ categoryId }


Load non Static Classes


<#assign assetEntryQuery = objectUtil("com.liferay.portlet.asset.service.persistence.AssetEntryQuery") />
<#assign assignedCategoryIdsNew=assetEntryQuery.getAllCategoryIds()/>


Find the Index of Element in The array


<#assign selectVocab = ["Department", "Client Scope"] />
<#if selectVocab?seq_index_of("Department") gt -1>
<#--  Do something -->
</#if>


Access Liferay Services in FTL


<#assign AssetCategoryLocalService = serviceLocator.findService("com.liferay.portlet.asset.service.AssetCategoryLocalService")>


Note:

To access Liferay Services in FTL we need to use following properties in portal-ext.properties file then only services will be available to the FTL


freemarker.engine.restricted.classes=
freemarker.engine.restricted.variables=


Try Following Code in the Asset Publisher ADT


<#assign aui = taglibLiferayHash["/WEB-INF/tld/aui.tld"] />
<#assign liferay_portlet = taglibLiferayHash["/WEB-INF/tld/liferay-portlet.tld"] />
<#assign liferay_ui = taglibLiferayHash["/WEB-INF/tld/liferay-ui.tld"] />
<#assign queryUtil = staticUtil["com.liferay.portal.kernel.dao.orm.QueryUtil"]/>
<#assign AssetCategoryLocalService = serviceLocator.findService("com.liferay.portlet.asset.service.AssetCategoryLocalService")>
<#assign AssetVocabularyLocalService = serviceLocator.findService("com.liferay.portlet.asset.service.AssetVocabularyLocalService")>
<#assign listVecoblaries = AssetVocabularyLocalService.getGroupVocabularies(themeDisplay.getSiteGroupId())>
<#assign AssetVocabularyLocalService = serviceLocator.findService("com.liferay.portlet.asset.service.AssetVocabularyLocalService")>
<@liferay_portlet.renderURL var="filterByCategory" windowState="normal">
</@liferay_portlet.renderURL>
<@aui.form action="${filterByCategory}" method="post" name="filterForm">
<#if listVecoblaries?has_content>
<#list listVecoblaries as vecobulary>
<@aui.select name="mycategoryId" id="categoryId" label="">
<@aui["option"] label="${vecobulary.getName()}" value="0"/>
<#assign listVecoblaryCategories = AssetCategoryLocalService.getVocabularyRootCategories(vecobulary.getVocabularyId(), queryUtil.ALL_POS, queryUtil.ALL_POS, null)>
<#if listVecoblaryCategories?has_content>
<#list listVecoblaryCategories as category>
<@aui["option"] label="${category.getName()}" value="${category.getCategoryId()}"/>
</#list>
</#if>
</@aui.select>
</#list>
</#if>
<@aui.button type="submit" value="Submit"></@aui.button>
</@aui.form>


When we use above FTL code in Asset Publisher then we can see all vocabularies as Select Box and its categories will become as options in the drop down box.

The following is result view for above FTL



 Author

Friday, April 17, 2015

Liferay Inter Portlet Communication (IPC)

Liferay Inter Portlet Communication (IPC) is mechanism to communicating one Portlet to other Portlet.

JSR 168/ Portlet 1.0 have very limited capability to provide Liferay Inter Portlet Communication (IPC) and its used Portlet Session to share data among Portlets.

JSR 286/Portlet 2.0 has added many ways to support Liferay Inter Portlet Communication (IPC) and it provides better approaches than what JSR 168 is already provided.



Liferay Portal will support all types of Inter Portlet Communication (IPC) that JSR 168 and JSR 286 provided.

When IPC comes into picture we can have two types of Portlets that is Sender Portlets and Receiver Portlets another way we can say Producer Portlets and Consumer Portlets.

Sender/Producer Portlet will send some data that is sharable to other Portlets and 
Consumer/Receiver/Listener Portlets are will receive data which already shared by producer/Sender Portlets. IPC can made with in the page or across the portal

Some of IPC mechanism only possible with in the page means all Portlets should be in the same and some other can support IPC among all Portlets which are in different pages or we can say across portal Portlets.

We have following Types of IPC Mechanisms which Liferay portal can support.

  1. Portlet Sessions IPC
  2. Public Render Parameters IPC
  3. IPC Events
  4. Client Side IPC with AJAX
  5. Client Side IPC with Cookies


From JSR 168/Portlet 1.0 we have feature of Inter Portlet Communication with Portlet Sessions.
Each Portlet have its own session that is called Portlet Session and session data won’t be shared with other Portlets.

To make Inter Portlet Communication with help of Portlet session we will make Portlet session as public so that data will be shared in other Portlets.


Available from JSR 168 and carried to JSR 286

Communication can be possible with in the page and across the portal


Public Render Parameters are the one of the way to make Inter Portlet Communication among the Portlets and these Portlets may be in same page or different pages in the portal.

Public Render Parameters we will define specific parameter in the Portlet with help of that data will be carried from one Portlet to other Portlet and these Public Render Parameters accessible by specific Portlet where we already defined these parameters.

IPC we have two categories of Portlets Sender Portlet and Receiver Portlets. Sender Portlet will send some data or push some data then receiver Portlet will receive the data and will process subsequent steps.

Available from JSR 286

Communication can be possible with in the page and across the portal



IPC Events is one of the ways to make Inter Portlet Communication among the Portlets and these Portlets may be in same page or different pages in the portal.

IPC Events we have two categories of Portlets Event Producer Portlet and Event Listener Portlets. Producer Portlet will send some data or push some data then Listener Portlet will receive the data and will process subsequent steps.

We can have one Producer and Multiple Consumer Portlet will listen the event and process subsequent steps.

Available from JSR 286

Communication can be possible with in the page and across the portal



Client Side Inter Portlet Communication is one of the ways in IPC this can apply the Portlet which reside in same page. Because Client side IPC will uses java script to communicate that’s why all Portlet which participated in IPC need to be in same page.

Liferay already have some java script library to implement client side IPC in Portlet Development.
Available from JSR 286

Communication can be possible with in the page only


Client Side IPC with Cookies

Same Like Client Side IPC with AJAX we can also achieve IPC through browser cookies and data will be stored in cookies and this will be accessed by other portlets and this have some limitation with respect data storage and security wise means I can store very limited data and sometime browsers may disable cookies then communication will be failed among Portlets.

Available from JSR 286

Communication can be possible with in the page only

Suggestible priority order as per my knowledge

  1. IPC Events
  2. Public Render Parameters IPC
  3. Portlet Sessions IPC 
  4. Client Side IPC with AJAX
  5. Client Side IPC with Cookies

Recent Posts

Recent Posts Widget

Popular Posts