Saturday, February 21, 2015

Store Portlet Preferences using Portlet Edit Mode

Portlet Preferences is the way to store Portlet specific information in the Portlet development. Generally if we wanted to add Portlet specific behaviour then we will use Portlet preferences.

Assume we want display date with different date format to each Portlet based on our need to so to make this I will store date format value in Portlet preferences.

We will use edit mode or edit page to configure Portlet related preferences to make this first we need add edit mode capability to portlet so that in the Portlet configuration we can see preferences link in the menu and when we click the link it will navigate to edit page.

Add Edit Mode capability to Portlet

We need to create edit JSP page
Need to do following configuration in the portlet.xml file

<portlet>
           <portlet-name>portlet-preferenses-action</portlet-name>
           <display-name>Portlet Preferenses</display-name>
           <portlet-class>
                com.meeera.liferay.PortletPreferensesAction
          </portlet-class>
           <init-param>
                <name>view-template</name>
                <value>/html/jsps/view.jsp</value>
           </init-param>
           <init-param>
                <name>edit-template</name>
                <value>/html/jsps/edit.jsp</value>
           </init-param>
           <expiration-cache>0</expiration-cache>
           <supports>
                <mime-type>text/html</mime-type>
                <portlet-mode>view</portlet-mode>
                <portlet-mode>edit</portlet-mode>
           </supports>
           <portlet-info>
                <title>Portlet Preferenses</title>
                <short-title>Portlet Preferenses Action</short-title>
                <keywords></keywords>
           </portlet-info>
           <security-role-ref>
                <role-name>administrator</role-name>
           </security-role-ref>
           <security-role-ref>
                <role-name>guest</role-name>
           </security-role-ref>
           <security-role-ref>
                <role-name>power-user</role-name>
           </security-role-ref>
           <security-role-ref>
                <role-name>user</role-name>
           </security-role-ref>
     </portlet>

Note:

Above red color xml tags will add edit mode capability to the Portlet. There we can edit template init param and its value that is jsp path of edit page.

When we add edit mode capability to Portlet then we can see preferences link in the Portlet configuration menu.

When we click the link it will go to edit page and when we observed URL of Portlet we can see request param name Portlet mode and its value is edit.

The following screen show preferences link in the Portlet configuration


When we click preferences link the URL we can see Portlet mode param values as edit.

http://localhost:8080/web/guest/test?p_p_id=portletpreferensesaction_WAR_StorePreferensesInPortletEditModeportlet&
p_p_lifecycle=0&p_p_state=normal&p_p_mode=edit&p_p_col_id=column-1

When we call above URL then it will execute doEdit(--)  method of Portlet action class which is one of the method implemented in the MVCPortlet.java class

The following is implementation was present in MVCPortlet.java for doEdit(--)

@Override
     public void doEdit(
                RenderRequest renderRequest, RenderResponse renderResponse)
           throws IOException, PortletException {

           PortletPreferences portletPreferences = renderRequest.getPreferences();

           if (portletPreferences == null) {
                super.doEdit(renderRequest, renderResponse);
           }
           else {
                include(editTemplate, renderRequest, renderResponse);
           }
     }


Create Portlet URL that will execute doEdit(--) method

The Portlet URL to execute doEdit(--) method we need to use attribute portletMode and value should be "edit" so that when we call this URL its will execute edit method of Portlet action class.

We override doEdit(--) method in our Custom Portlet Action it will execute our overridden method otherwise it will execute the super class doEdit(--) method that is MVCPortlet.

Example to create URL to execute doEdit(--)   method

Render URL with Edit Mode

<portlet:renderURL var="savePreferensesActionURL" windowState="normal" portletMode="edit">
</portlet:renderURL>

Action URL with Edit Mode

<portlet:actionURL var="savePreferensesActionURL" windowState="normal" portletMode="edit">
</portlet:actionURL>

Store Portlet Preferences in the Portlet Edit Mode

Now we will store Portlet preferences or we can Portlet configuration values using Portlet edit mode to make this we need follow following steps

Steps:
  1. Add Edit Mode capability to Portlet
  2. Override doEdit(--)  method in Custom Portlet Action
  3. Get Portlet Preferences Values in View pages and Present Data as for Portlet preferences.

Add Edit Mode capability to Portlet

We need to create edit JSP page
Need to do following configuration in the portlet.xml file

<portlet>
           <portlet-name>portlet-preferenses-action</portlet-name>
           <display-name>Portlet Preferenses</display-name>
           <portlet-class>
                com.meeera.liferay.PortletPreferensesAction
           </portlet-class>
           <init-param>
                <name>view-template</name>
                <value>/html/jsps/view.jsp</value>
           </init-param>
           <init-param>
                <name>edit-template</name>
                <value>/html/jsps/edit.jsp</value>
           </init-param>
           <expiration-cache>0</expiration-cache>
           <supports>
                <mime-type>text/html</mime-type>
                <portlet-mode>view</portlet-mode>
                <portlet-mode>edit</portlet-mode>
           </supports>
           <portlet-info>
                <title>Portlet Preferenses</title>
                <short-title>Portlet Preferenses Action</short-title>
                <keywords></keywords>
           </portlet-info>
           <security-role-ref>
                <role-name>administrator</role-name>
           </security-role-ref>
           <security-role-ref>
                <role-name>guest</role-name>
           </security-role-ref>
           <security-role-ref>
                <role-name>power-user</role-name>
           </security-role-ref>
           <security-role-ref>
                <role-name>user</role-name>
           </security-role-ref>
     </portlet>
Note:

Above red color xml tags will add edit mode capability to the Portlet. There we can edit template init param and its value that is jsp path of edit page.

In the edit.jsp page we need to create form with input elements that is Portlet preferences which we are taking from user/client for this Portlet.

We already assumed we wanted display different date format to date when we display current date in Portlet.  Here we will take date format as Portlet preferences as form input

We will submit our form using Portlet render URL and that is in the edit mode so that it will execute the Portlet doEdit(--) method in Portlet action class, there we will capture user from inputs and store into databased as Portlet preferences .

The following is code in edit.jsp page

<%@page import="com.liferay.portal.kernel.util.StringPool"%>
<%@page import="com.liferay.portlet.PortletPreferencesFactoryUtil"%>
<%@page import="com.liferay.portal.kernel.util.Validator"%>
<%@page import="com.liferay.portal.kernel.util.ParamUtil"%>
<%@page import="javax.portlet.PortletPreferences"%>
<%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>
<portlet:defineObjects />
<portlet:renderURL var="savePreferensesRenderURL" windowState="normal" portletMode="edit">
</portlet:renderURL>
<%
PortletPreferences preferences = renderRequest.getPreferences();
String portletResource = ParamUtil.getString(request, "portletResource");
if (Validator.isNotNull(portletResource)) {
preferences = PortletPreferencesFactoryUtil.getPortletSetup(request, portletResource);
}
String dateFormat = preferences.getValue("dateFormat",null);
%>
<h1> Add Portlet Preferenses</h1>
<form action="<%=savePreferensesRenderURL%>" name="savePreferenses"  method="POST">
Expected Date Format<br/>
<input  type="text" name="<portlet:namespace/>prefdateformat"<portlet:namespace/>prefdateformat" value='<%=dateFormat!=null?dateFormat:StringPool.BLANK%>'/><br/>
<input type="submit" name="savepref" id="savepref" value="Save Preferenses"/>
</form>

Override doEdit(--)  method in Custom Portlet Action

Now we need to override doEdit(--) method in our Portlet Action class so that here we will write preferences storing logic and  the values store into the database on behalf  of Portlet. 

It will use portlet preferences database table where it will store all preferences with portlet id and all values will make it as XML string and store in the table.

The following is Custom Portlet Action class with doEdit(--) and preferences storing

public class PortletPreferensesAction extends MVCPortlet {
      @Override
     public void doEdit(RenderRequest renderRequest,
                RenderResponse renderResponse) throws IOException, PortletException {
           String dateFormat = ParamUtil
                     .getString(renderRequest, "prefdateformat");
           System.out.println("====" + dateFormat);
           PortletPreferences preferences = renderRequest.getPreferences();
           String portletResource = ParamUtil.getString(renderRequest,
                     "portletResource");
           if (Validator.isNotNull(portletResource) && (preferences == null)) {
                try {
                     preferences = PortletPreferencesFactoryUtil.getPortletSetup(
                                renderRequest, portletResource);
                } catch (PortalException e) {
                     // TODO Auto-generated catch block
                     e.printStackTrace();
                } catch (SystemException e) {
                     // TODO Auto-generated catch block
                     e.printStackTrace();
                }
           }
           preferences.setValue("dateFormat", dateFormat);
           preferences.store();
           SessionMessages.add(renderRequest,"potlet-config-saved");
           super.doEdit(renderRequest, renderResponse);
          
     }
    
}

Get Portlet Preferences Values in View page and Present Data as for Portlet preferences.

Finally we will take the preferences values from portlet preferences and will display view as for preferences stored for that particular Portlet.

In our case we will take date format that configured by user and display current date with user desired format.

When we take the values from preference object with getValue(--) method we need to pass default value as second parameter so that it will use when the preferences value is not available.

The following is Sample Code in the view.jsp

<%@page import="java.util.Date"%>
<%@page import="java.text.SimpleDateFormat"%>
<%@page import="com.liferay.portlet.PortletPreferencesFactoryUtil"%>
<%@page import="com.liferay.portal.kernel.util.Validator"%>
<%@page import="com.liferay.portal.kernel.util.ParamUtil"%>
<%@page import="javax.portlet.PortletPreferences"%>
<%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>

<portlet:defineObjects />

<%
PortletPreferences preferences = renderRequest.getPreferences();
String portletResource = ParamUtil.getString(request, "portletResource");
if (Validator.isNotNull(portletResource)) {
preferences = PortletPreferencesFactoryUtil.getPortletSetup(request, portletResource);
}
String dateFormat = preferences.getValue("dateFormat",null);
%>
<%
if(dateFormat!=null){
SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
String date = sdf.format(new Date());
out.println("Today Date:"+date);
}else{
     out.println("Please configure date format");
}

%>
Portlet Screens:

Following screen shows navigate to portlet edit mode or edit jsp page



The following is Store Date format preferences from edit page


Display Current Date in view page with desired data format


Download Store Preferences in Edit Mode Portlet


Another way also we can store Portlet preferences using Liferay Configuration Action mechanism



Popular Posts

Recent Posts

Recent Posts Widget