Coordination between portlets across pages

There has been lot of queries asking me how to send/receive events with portlets that are not on same page. So I thought let me blog about this.

In order to provide coordination between portlets the Java Portlet Specification, JSR 286 introduces Eventing and Public Render Parameters

Eventing:

   By default portlets can send and receive events with other portlets that are on the same page. This can be changed to enable portlets to send and receive events from other portlets that are on different pages. This can be done by adding the following property in portal-ext.properties in Web Space server and Liferay Portal 5.2.x.

portlet.event.distribution=ALL_PORTLETS


Public Render Parameters:

   By default portlets can share render states with other portlets that are on the same page. This can be changed to enable portlets to share render states with other portlets that are on different pages. This can be done by adding the following property in portal-ext.properties in Web Space server and Liferay Portal 5.2.x.

portlet.public.render.parameter.distribution=ALL_PORTLETS


Preventing infinite loops in Eventing:

    The following property is used to specify the maximum number of events that can be generated from portlets to prevent infinite loops. If a portlet sends an event to other portlets, it is considered as one event generation. If the other portlets send events, that is considered as two event generations and so on. The default value is 3.

portlet.event.max.generation=3

Comments:

Hi,

I´m developing with liferay 5.2.3, tomcat 6.0.18 and JDK 1.6 update 16.
I have two portlet with events communication. When I use default portlet container implementation(portlet.container.impl). It works ok, but when I change to sun implementation (portlet.container.impl=sun) I can send the event but the portlets can´t receive the event. The portlets are in the same page (next level will be send events with portlets in differents pages).
Maybe I have wrong versions?, There isn´t any exception in the console.
Please could you help me?

Posted by Miguel on September 14, 2009 at 08:13 AM IST #

When you change to sun implementation, you need to redeploy the portlet wars. Once you have done that you can switch between the implementations.

Posted by Deepak on September 14, 2009 at 08:24 AM IST #

Hi Deepak,

I've two portlets(A and B - in the same .war file) in two different pages. For me, eventing works fine when the portlets are in the same page. Now, when I am trying to implement IPC between pages, the processEvent(req, res) method is not being triggered in portlet B from portlet A. I've been trying to implement IPC between pages for about 5 days and no success yet. I tried all possibilities in eventing but no luck. I would be glad if you can help me out and here is my environment
1)liferay-portal-5.2.3 + tomcat-6.0.18
2)jdk1.6.0_07

I've also set
portlet.container.impl=internal
portlet.event.distribution=ALL_PORTLETS
in portal-ext.properties in ${TOMCAT}\\webapps\\ROOT\\WEB-INF\\classes folder

here is my complete portlet.xml file

<?xml version="1.0" encoding="UTF-8"?>

<portlet-app xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0"
xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd">
<portlet>
<portlet-name>simple_portlet</portlet-name>
<display-name>Simple Portlet</display-name>
<portlet-class>com.liferay.portlet.first.FirstPortlet</portlet-class>

<init-param>
<name>com.sun.faces.portlet.INIT_VIEW</name>
<value>/view.jsp</value>
</init-param>
<expiration-cache>0</expiration-cache>
<supports>
<mime-type>text/html</mime-type>
</supports>
<portlet-info>
<title>Simple Liferay Portlet</title>
<short-title>Simple Liferay Portlet</short-title>
<keywords>Simple Liferay Portlet</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>
<supported-publishing-event>
<qname xmlns:x="http:sun.com/userevents">x:UserBean</qname>
</supported-publishing-event>
</portlet>

<portlet>
<portlet-name>user_portlet</portlet-name>
<display-name>User Portlet</display-name>
<portlet-class>com.liferay.portlet.second.UserPortlet</portlet-class>

<init-param>
<name>com.sun.faces.portlet.INIT_VIEW</name>
<value>/userWelcome.jsp</value>
</init-param>
<expiration-cache>0</expiration-cache>
<supports>
<mime-type>text/html</mime-type>
</supports>
<portlet-info>
<title>Second Liferay Portlet</title>
<short-title>Second Liferay Portlet</short-title>
<keywords>Second Liferay Portlet</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>
<supported-processing-event>
<qname xmlns:x="http:sun.com/userevents">x:UserBean</qname>
</supported-processing-event>
</portlet>

<event-definition>
<qname xmlns:x="http:sun.com/userevents">x:UserBean</qname>
<value-type>com.jsf.bean.UserBackingBean</value-type>
</event-definition>
</portlet-app>

Posted by Sravan Patti on December 04, 2009 at 04:07 AM IST #

You need to set portlet.container.impl=sun in portal-ext.properties. And restart Tomcat. After restart, you need to redeploy the war. Then try again.

Posted by Deepak on December 04, 2009 at 10:22 AM IST #

Hi Deepak,

I've also tried the option of setting portlet.container.impl=sun in portal-ext.properties but it is showing "null" in both the portlets. I tried restarting tomcat and redeplying the war file several times but of no use.
For more information, I am using JSF for developing portlets. I'll also paste my web.xml and faces-config.xml

web.xml

<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">
<context-param>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>client</param-value>
</context-param>
<context-param>
<param-name>javax.faces.application.CONFIG_FILES</param-name>
<param-value>/WEB-INF/faces-config.xml</param-value>
</context-param>
<context-param>
<param-name>com.sun.faces.validateXml</param-name>
<param-value>false</param-value>
</context-param>
<listener>
<listener-class>
com.liferay.portal.kernel.servlet.PortletContextListener</listener-class>
</listener>
<display-name>LiferayProject</display-name>
<servlet>
<servlet-name>simple portlet</servlet-name>
<servlet-class>com.liferay.portal.kernel.servlet.PortletServlet</servlet-class>
<init-param>
<param-name>portlet-class</param-name>
<param-value>com.liferay.portlet.first.FirstPortlet</param-value>
</init-param>
<load-on-startup>0</load-on-startup>
</servlet>

<servlet>
<servlet-name>user portlet</servlet-name>
<servlet-class>com.liferay.portal.kernel.servlet.PortletServlet</servlet-class>
<init-param>
<param-name>portlet-class</param-name>
<param-value>com.liferay.portlet.second.UserPortlet</param-value>
</init-param>
<load-on-startup>0</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>simple portlet</servlet-name>
<url-pattern>/simple_portlet/\*</url-pattern>
</servlet-mapping>

<servlet-mapping>
<servlet-name>user portlet</servlet-name>
<url-pattern>/user_portlet/\*</url-pattern>
</servlet-mapping>

<servlet>
<servlet-name>FacesServlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>FacesServlet</servlet-name>
<url-pattern>/faces/\*</url-pattern>
</servlet-mapping>
<security-constraint>
<web-resource-collection>
<web-resource-name>Page Sources</web-resource-name>
<url-pattern>\*.jsp</url-pattern>
<url-pattern>\*.jspx</url-pattern>
<url-pattern>\*.xhtml</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>nobody</role-name>
</auth-constraint>
</security-constraint>
<security-role>
<role-name>nobody</role-name>
</security-role>
</web-app>

faces-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE faces-config PUBLIC "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.1//EN"
"http://java.sun.com/dtd/web-facesconfig_1_1.dtd">
<faces-config>
<managed-bean>
<managed-bean-name>user</managed-bean-name>
<managed-bean-class>com.liferay.samplejsfsun.bean.UserBean</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
<managed-bean>
<managed-bean-name>userBean</managed-bean-name>
<managed-bean-class>com.jsf.bean.UserBackingBean</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
<managed-bean>
<managed-bean-name>address</managed-bean-name>
<managed-bean-class>com.liferay.samplejsfsun.bean.AddressBean</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
<navigation-rule>
<from-view-id>/view.jsp</from-view-id>
<navigation-case>
<from-outcome>submit</from-outcome>
<to-view-id>/welcome.jsp</to-view-id>
</navigation-case>
</navigation-rule>
<navigation-rule>
<from-view-id>/welcome.jsp</from-view-id>
<navigation-case>
<from-outcome>back</from-outcome>
<to-view-id>/view.jsp</to-view-id>
</navigation-case>
</navigation-rule>
<navigation-rule>
<from-view-id>/userWelcome.jsp</from-view-id>
<navigation-case>
<from-outcome>submit</from-outcome>
<to-view-id>/welcome.jsp</to-view-id>
</navigation-case>
</navigation-rule>
</faces-config>

Posted by Sravan Patti on December 07, 2009 at 12:59 AM IST #

Can you send the war to users@portlet-container.dev.java.net?

Posted by Deepak on December 07, 2009 at 02:48 AM IST #

Are you trying eventing with two JSF portlets? Which JSF Portlet Bridge are you using? When eventing works fine when the portlets are in the same page...were you referring to JSF Portlets or JSR286 portlets?

Posted by Deepak on December 07, 2009 at 06:12 AM IST #

Hi Deepak,

Can you send me step by step procedure for Event bases inter portlet communication across different pages for the above scenario??
Or else please give me a link of the working project in liferay-portal-5.2.3 + tomcat-6.0.18 along with sources.

Posted by Sravan patti on December 18, 2009 at 03:38 AM IST #

Also, when I use portlet.container.impl=sun in portal-ext.properties, all portlets are showing as "NULL"

Posted by Sravan Patti on December 18, 2009 at 03:45 AM IST #

Hi,
After you add portlet.container.impl=sun in portal-ext.properties you should redeploy the portlets. Make sure portal-ext.properties has portlet.event.distribution=ALL_PORTLETS
You can try the eventing sample from https://portlet-container.dev.java.net/public/Samples.html . It has three portlets, you can add(via Add Application) the portlets on different pages. And you will notice that clicking on World Map will change the content in other portlets.

Posted by Deepak on December 18, 2009 at 04:05 AM IST #

Hi Deepak,

I tried the samples.The portlets works fine when they are in the page but doesn't work when they are in different pages. I've added portlet.container.impl=sun and portlet.event.distribution=ALL_PORTLETS in portal-ext.properties. I redeployed the portlet war file many times, but no success yet and the portlets show "null".
When I remove portlet.container.impl=sun from portal-ext.properties, the portlets appear but doesn't work when they are in the different page.
Please help me!!!

Posted by Sravan Patti on December 21, 2009 at 12:50 AM IST #

If you are using Tomcat, you should use JDK6 as the JVM. Also check the web.xml of the portlet webapp in tomcat-home/webapps/<portlet-webapp>/WEB-INF/web.xml, you should see the entry for PortletAppEngineServlet

Posted by Deepak on December 21, 2009 at 04:44 AM IST #

Hi Deepak,
the IPC of portlets which are on defferent pages works fine. But now I want to extend it by navigation between the portal pages. So I have a portalpage PAGE1 with the portlet PORTLET1 and the portalpage PAGE2 with the portlet PORTLET2. In my portlet PORTLET1 i have a button which sets a public render parameter. After a click on the button I want to navigate to the PAGE2 where the publich render parameter will shown within the PORTLET2.
I've tried to send a redirect within the processAction method

public void processAction(ActionRequest actionRequest, ActionResponse actionResponse) throws PortletException, IOException {
super.processAction(actionRequest, actionResponse);
actionResponse.sendRedirect("http://localhost:8080/web/guest
/privatepage2");
}

The redirect works fine if I don't set the render parameter and don't call
super.processAction(actionRequest, actionResponse);

But whe I do it, the redirect don't works because of the Exception
"Illegal to sendRedirect after setting window state, portlet mode, or render parameters".

I now this behavior is defined by the portlet spec., but how can I achieve the page to page navigation and the IPC?
You know a solution for that?

(I am using Liferay 5.2.3 on JBoss 5.1 with the JBoss portletbridge 2.0.0.CR1 and JSF RI 1.2_13)

Thank you for help!!!

Posted by Konrad on March 04, 2010 at 12:28 PM IST #

If you want to handle sharing of public render parameter across pages, then as mentioned in this blog, you need set the parameter portlet.public.render.parameter.distribution=ALL_PORTLETS in portal-ext.properties. This works if the portlet.container.impl=sun is set in portal-ext.properties. After this change you need to restart the webcontainer.

Posted by Deepak on March 05, 2010 at 09:09 AM IST #

Hi,
yes i've done this and it's works very well, as I said in the last post ("the IPC of portlets which are on defferent pages works fine").
But there is an other question in my last post regarding to the navigation from one portal page to the other page.
At the moment I can set the public render parameter within my PORTLET1 (for example by inputting the city and press on the submitt button). After that I can go to the other portal page by clicking the corresponding tab and see the city within the PORTLET2 on PAGE2.
But what I want is that after I click to the submit button on PORTLET1 on PAGE1, the public render parameter (city) will set and I will redirected to the PAGE2 (automatically) where I can see the city within my PORTLET2.
As I said in my last post, I tried it by actionResponse.sendRedirect("http://localhost:8080/web/gues/privatepage2"); but it's not working (see my last post).

Thank you!!!

Posted by Konrad on March 07, 2010 at 09:33 AM IST #

Hi,
when I use the sun portlet container (portlet.container.impl=sun) than the "coordination between portlets across pages" works well. But like I discribed in my previous posts, I have a problem when I want to navigate from page to page.
When I use the liferay's internal portlet container (portlet.container.impl=internal) than the "coordination between portlets across pages" is not working, but the navigation from page to page I can achieve by setting the following

actionResponse.setProperty("referer", "http://localhost:8080/web/guest/privatepage2");

:-)
It's very pity that no container provides both features.
So I think I have to realise the communication of portlets by using the portlet session.

Posted by Konrad on March 11, 2010 at 12:36 PM IST #

You have an idea?

Posted by Konrad on March 12, 2010 at 02:33 PM IST #

Rather than setting the render parameter and send it to across to other portlet, you can send it via URL parameter to the other portlet. Can you try with sendRedirect(String location, String renderUrlParamName), and then in portlet2, you need to use HttpServletRequest to get access to the parameters.

Posted by Deepak on March 15, 2010 at 08:04 AM IST #

Hi Deepak,

Currently my environment is Liferay 5.2.3 + WAS 6.1.0.27. I need help in IPC across the pages between two portlets using event based mechanism. I tried adding "portlet.event.distribution=ALL_PORTLETS" in portal-ext.properties but didn't find any luck. I would be gald if I can get any information on this.

Posted by Sravan Patti on May 03, 2010 at 12:23 PM IST #

in portal-ext.properties you need to set portlet.container.impl=sun and then redeploy the portlet.

Posted by Deepak on May 03, 2010 at 03:27 PM IST #

Hello !!,
My requirement is as follows:

1) on a page, i hv 4 portlets out of which 1 is the ControllerPortlet which is always visible. The other 3 need to be invisible by default when the Page Loads.
I hv done this by setting setVisible(false) for each of the 3 portlets' presentationContexts in the doView of the ControllerPortlet

2) now from the ControllerPortlet, i hv checkboxes to hide/show any of the 3 portlets one at a time
when i try to make any of the 3 portlets visible i get an error in a browser popup :
"ERROR: [EXCEPTION] Unable to locate tag with id ajax"

I get this error ONLY when i keep the 3 portlets invisible initially (on page load).

If i have the portlets as visible initially (on page load) & then try to make them invisible, then it works fine.

Please provide any clues on how to keep portlets invisible by default & then make them visible

Thanks !!

Posted by deepa on June 20, 2010 at 12:42 PM IST #

on which portlet container are you trying this? This may be because the DOM is not fully constructed after serve resource call, hence the error/exception.

Posted by Deepak on June 21, 2010 at 03:47 AM IST #

Hello Deepak .. thanks so much for your prompt reply ..

1) I am using Weblogic Portal 10.3.2 and all portlets are java portlets.
2) in the ControllerPortlet's doView i am invoking the presentationContexts of each of the 3 portlets & setting setVisible(false), so that the 3 portlets are not rendered on PageLoad
3) in the ControllerPortlet's jsp i hv checkboxes by which i want to dynamically show any of the 3 portlets one at a time. I have done this by setting backingContext.setVisible for the respective portlet in the processAction of the ControllerPortlet.
4) Also to ensure that the remaining 2 portlets do NOT re-render, i am setting a Public Render Param in the processAction of the ControllerPortlet for each portlet, so that only the selected Portlet (which has subscribed to the public render param) gets triggered

For eg. if I select Portlet1 from the ControllerPortlet for showing dynamically, the ControllerPortlet's processAction sets the Portlet1BackingContext.setVisible(true) & also does actionResponse.setRenderParam("prp_portlet1", "show"). The prp_portlet1 is a public render param to which only the Portlet1 is subscribed (thru the Supported Public render param tag in porlet.xml) and hence Portlet1's doView gets executed (as required). However when the response comes to the browser, the javascript is unable to find the ajax tag for portlet1 (because it was never rendered on page load) & gives the error.
Instead if I do NOT hide the portlets by default (on page load) & then try to dynamically hide/show them it works perfectly fine.
But my requirement is to keep them hidden by default & dynamically show them one by one without impacting the other portlets.

Can you please guide me on how to achieve this?

Thanks again ..

Posted by Deepa on June 21, 2010 at 05:23 AM IST #

Will the Inter Portlet communication works across portlets in different wars?

Posted by Dan on October 14, 2010 at 10:58 AM IST #

Yes..If you are running in Tomcat, the JRE should be JDK6, as the internally the eventing uses JAXB for communicating across wars.

Posted by Deepak on October 14, 2010 at 11:12 AM IST #

In Liferay I have a custom search form in portlet which publishes event to other portlet on another page (portlet.event.distribution=ALL_PORTLETS), but other users on other browsers see what I entered into search form

are event data application scoped ? how do I restrict only to the one user (session)

Posted by Jack Bakker on November 18, 2010 at 05:39 AM IST #

It depends on the how the portlet is written to display the information it receives. After obtaining the event payload via eventRequest, you can set data in the session so that only that user can see it.

Posted by Deepak on November 18, 2010 at 08:14 AM IST #

got it thanks ; take from eventRequest, put in

eventRequest.getPortletSession().setAttribute

then doView, etc can grab it

Posted by Jack Bakker on November 18, 2010 at 03:25 PM IST #

My Project structure is such that each of the portlets reside in different projects(different wars).

Eg. EmployeeDetails and AddressPortlet are the two portlets and 2 pages have been created for these portlets.
Say I am on the EmployeeDetails page and from here I want to navigate to AddressPortlet which is residing on the separate page.

I setting the following parameters in portal-ext.properties

portlet.event.distribution=ALL_PORTLETS
portlet.public.render.parameter.distribution=ALL_PORTLETS
portlet.container.impl=sun

Now what happens is when I click on the link( which has to take me to address details page) on the employee details page, the processEvent of the AddressPortlet gets invoked. Now instead of the doVIew method of the AddressPortlet getting invoked, the doView method of EmployeeDetails(Sender Portlet) gets invoked.

Any idea why this could be occurring?

Posted by siddhi on December 13, 2010 at 07:56 AM IST #

[Trackback] True. I can't see any alternative - no working code like here http://community.jboss.org/thread/161519?tstart=0 - no additional configurations as here http://blogs.sun.com/deepakg/entry/coordination_between_portlets_across_pages portlet.container....

Posted by JIRA: exo-portal (1.x, 2.x) on January 21, 2011 at 06:11 PM IST #

perhaps link to action in first portlet which at end of action redirects with

actionResponse.sendRedirect("/path/to/secondPage");

(yes doView of first portlet still gets invoked which is a waste of cycles )

--

another option also not ideal is to have link go to action and :

actionResponse.setRenderParameter("redirect",url);

where url can have other request parameters

--

Posted by Jack Bakker on January 21, 2011 at 08:19 PM IST #

In event case IPC between two portlets on different pages are not working

Posted by guest on August 18, 2011 at 11:22 AM IST #

In which version of liferay you tried? Its supported in Web Space server and Liferay Portal 5.2.x.

Posted by Deepak on August 18, 2011 at 11:26 AM IST #

I tried in Liferay 6 SP1 and SP2.In both its not working

Posted by ANKIT on August 18, 2011 at 12:12 PM IST #

In Liferay 6, the keywords are different. I think it is portlet.event.distribution=layout or portlet.event.distribution=layout-set

Posted by Deepak on August 18, 2011 at 12:28 PM IST #

Anyone tried in Liferay 6 sp1 and sp2,I tries with
portlet.event.distribution=layout
portlet.event.distribution=layout-set

but its not working
any guess?

Posted by ANKIT SRIVASTAVA on September 12, 2011 at 01:52 PM IST #

If its not working as stated, have you tried posting in Liferay forum on this issue?

Posted by guest on October 05, 2011 at 09:21 AM IST #

We are in a Oracle webcenter 11g environment. I do not see a way to provide settings in the the portlet-ext.properties like in Liferay.

Is there any way we can publish/receive events across pages in Oracle Webcenter 11g PS3?

All events work fine when the 2 portlets are on the same page but when the publisher and receiver are on seperate pages, it does not work.

Thanks in advance.

Posted by MS on November 03, 2011 at 03:35 PM IST #

We are in a Oracle webcenter 11g environment. I do not see a way to provide settings in the the portlet-ext.properties like in Liferay.

Is there any way we can publish/receive events across pages in Oracle Webcenter 11g PS3?

All events work fine when the 2 portlets are on the same page but when the publisher and receiver are on seperate pages, it does not work.

Thanks in advance.

Posted by MS on November 03, 2011 at 03:35 PM IST #

Hi Deepak,

I am using oracle webcenter 11.1.1.4 (or 11.1.1.5) and running into problems with ipc with portlets in different applications on different pages.

Is there any way to pass events from portlet 1 page 1 to portlet 2 page 2?

Also is there any way to pass public render parameters from portlet 1 page 1 to portlet 2 page 2?

Thanks in advance!

Posted by guest on November 10, 2011 at 01:42 PM IST #

Sorry i dont know how it can be achieved in Oracle WebCenter. Can you try posting the query in Oracle Forum.

Posted by Deepak on November 17, 2011 at 03:23 AM IST #

Post a Comment:
  • HTML Syntax: NOT allowed
About

Deepak Gothe

Search

Categories
Archives
« April 2014
SunMonTueWedThuFriSat
  
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
   
       
Today