Dev @ Work

A day in the life of a developer

Liferay: Embedding Portlets in your Portlet

July 1st, 2011 by

In this article I will show you how you can embed an existing Liferay portlet into your own plug-in portlet without using Ext. This might be useful in several scenarios, for example: building your own ‘nested portlet’ portlet or include the web form portlet in your own portlet.

The solutions works in Liferay 6.0 EE SP1 and can include portlets from Liferay itself as well as portlets coming from other plug-ins. Other versions of Liferay have not been tested yet.

I hope this snippet is as useful to you as it is to me!

package nl.liones.liferay;
import com.liferay.portal.kernel.exception.SystemException;
import com.liferay.portal.kernel.portlet.PortletBag;
import com.liferay.portal.kernel.portlet.PortletBagPool;
import com.liferay.portal.kernel.util.WebKeys;
import com.liferay.portal.service.PortletLocalServiceUtil;
import com.liferay.portal.theme.PortletDisplay;
import com.liferay.portal.theme.ThemeDisplay;
import com.liferay.portal.util.PortalUtil;
import com.liferay.portal.util.PortletKeys;
import javax.portlet.PortletRequest;
import javax.portlet.PortletResponse;
import javax.portlet.ValidatorException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
/**
 * Portlet embed utility method.
 *
 * @author Stef Busking (Liones), Bert Willems (Liones)
 */
public class RuntimePortletEmbedUtil {
    /**
     * Renders the given portlet as a runtime portlet and returns the portlet's HTML.
     *
     * @param request     The {@link PortletRequest}.
     * @param response    The {@link PortletResponse}.
     * @param portletId   The ID of the portlet to render, includes instance ID for instance portlets.
     * @param queryString The query string to use for the portlet.
     * @return The HTML for the given portlet.
     * @throws SystemException    on error.
     * @throws IOException        on error.
     * @throws ServletException   on error.
     * @throws ValidatorException on error.
     */
    public static String renderPortlet(final PortletRequest request, final PortletResponse response, final String portletId, final String queryString) throws SystemException, IOException, ServletException, ValidatorException {
        // Get servlet request / response
        HttpServletRequest servletRequest = PortalUtil.getOriginalServletRequest(PortalUtil.getHttpServletRequest(request));
        HttpServletResponse servletResponse = PortalUtil.getHttpServletResponse(response);
        // Get theme display
        final ThemeDisplay themeDisplay = (ThemeDisplay) servletRequest.getAttribute(WebKeys.THEME_DISPLAY);
        // Backup current state
        PortletDisplay portletDisplay = themeDisplay.getPortletDisplay();
        PortletDisplay portletDisplayClone = new PortletDisplay();
        portletDisplay.copyTo(portletDisplayClone);
        final Map<String, Object> requestAttributeBackup = new HashMap<String, Object>();
        for (final String key : Collections.list((Enumeration<String>) servletRequest.getAttributeNames())) {
            requestAttributeBackup.put(key, servletRequest.getAttribute(key));
        }
        // Render the portlet as a runtime portlet
        String result;
        try {
            PortletBag implPortletBag = PortletBagPool.get(PortletKeys.JOURNAL);
            com.liferay.portal.model.Portlet portlet = PortletLocalServiceUtil.getPortletById(PortalUtil.getCompanyId(request), portletId);
            servletRequest.setAttribute(WebKeys.RENDER_PORTLET_RESOURCE, Boolean.TRUE);
            result = PortalUtil.renderPortlet(implPortletBag.getServletContext(), servletRequest, servletResponse, portlet, queryString, false);
        } finally {
            // Restore the state
            portletDisplay.copyFrom(portletDisplayClone);
            portletDisplayClone.recycle();
            for (final String key : Collections.list((Enumeration<String>) servletRequest.getAttributeNames())) {
                if (!requestAttributeBackup.containsKey(key)) {
                    servletRequest.removeAttribute(key);
                }
            }
            for (final Map.Entry<String, Object> entry : requestAttributeBackup.entrySet()) {
                servletRequest.setAttribute(entry.getKey(), entry.getValue());
            }
        }
        return result;
    }
}

Using this code
The snippet below demos how to embed the Liferay Web Form portlet and how to set a preference for this embedded portlet.

final String portletId = "1_WAR_webformportlet_INSTANCE_abcd";
final ThemeDisplay themeDisplay = (ThemeDisplay) request.getAttribute(WebKeys.THEME_DISPLAY);
// get the preferences
final PortletPreferences prefs = PortletPreferencesUtilityLocalServiceUtil.getWrappedPortletPreferences(themeDisplay, portletId);
// set a preference
prefs.setValue("successURL", "some url");
// dont forget to store the preferences
formPrefs.store();
// get the HTML from the portlet
final String portletHtml = RuntimePortletEmbedUtil.renderPortlet(request, response, portletId, "");
Posted in Java | 8 Comments »

Solving the Portlet Design Problem

December 22nd, 2010 by

In my previous post I told you about the problem we encountered while implementing the Kluwer Support portal in Liferay. In this post I will explain the solution we came up with.

But first lets have a quick look at the problem again: We needed to support different styles per portlet and ‘read more’ links which needed to work for both custom and out-of-the-box potlets. Let have a look at some of the different ‘web-content display portlet’ styles used in the portal:

Liferay, at least not version 5.2.8 EE, does not support these requirements out of the box (Not entirely true: Liferay does allow you to specify custom CSS rules per portlet instance, but you would need a front-end specialist to maintain the website which IMHO is not acceptable).

To make it even more difficult we were not allowed to use Liferay Ext or place many hooks or have impact on existing communities in the portal instance.

Read the rest of this entry »

Posted in Java | 8 Comments »

Building Kluwer Support Portal – a Developers Perspective

December 17th, 2010 by

In the past two months we (Liones) build a new Liferay based portal for Kluwer (a major Dutch publisher), one of our clients. The purpose of this portal is to help the customers of Kluwer online products to understand and use their products better. This week the Kluwer Support portal was launched with success and I reckoned this was a good moment to share some insight in how we developed that particular portal and what problems we encountered during the development.

But let’s have a look at the result first:

I hope you agree with me when I say that it looks great, I know for a fact a lot of people do. You can find the actual portal at http://www.kluwer.nl/support, although the portal is in Dutch, feel free to look around.

In the next few paragraphs I will share some challenges we faced and the lessons we learned while implementing the Kluwer Support portal.

Read the rest of this entry »

Posted in General, Java | 2 Comments »

My First Java Steps

August 25th, 2009 by

Hello all, sorry for the radio silence lately, you might wonder what I have been doing lately. Well I have committed a terrible sin against the .NET framework (my previous home :P ): I started learning Java.

Why Java? Because several clients of Liones demand that their applications must be build on the Java platform and I am deeply involved in the process. I am not going to bother you with the organizational side of the process, I will focus on sharing my experience.

Learning Java isn’t really the objective for me, it is just another programming language and C# is similar enough to not cause any problems for me to program in Java. The real objective is to be able to develop applications (called portlets) for the Liferay portal framework. The hidden challenge, for me, turned out to be setting up the environment.

I got everything up and running today: Java, Ant, Tomcat, Liferay and I developed my first custom portlet (an application for Liferay) using above technologies and Java Server Faces. I will post an article on how I did it soon!

Posted in Java | 1 Comment »

Implementing a front end for Microsoft Dynamics CRM

July 30th, 2009 by

Microsoft Dynamics CRM 4.0Today I was working at a custom front end application for Microsoft Dynamics CRM, a project I have been blogging about before. The goal of that project is to create a client portal showing information directly from the CRM. I am going to describe to you the 3 steps you need to take to implement your own front end for Microsoft Dynamics CRM.

Read the rest of this entry »

Asynchronous Payment Provider Implementation Pattern

March 17th, 2009 by

PaymentToday at Liones I started working on the integration of a payment service provider (PSP) for a web shop implementation. While I was thinking about the architecture I discovered that it is actually very straightforward and that most of the application flow is reusable in different implementations with other PSPs.

Take a look at the UML diagram below; you will notice that there are actually two flows:

  • One synchronous, which guides the user trough the payment screen
  • One asynchronous, which notifies when the payment state changed (payment is confirmed or canceled)

Read the rest of this entry »

Lucene.NET and Facetted Search

February 20th, 2009 by

LuceneFor my work at Liones I has to implement a Lucene.NET search solution, including drill-down/faceted search. This was pretty hard to accomplish because there wasn’t much reference material, at least not for C#, but I just finished the first implementation and it works like a charm. I am not going to discus the implementation in detail because I decided to write some articles about it.

For now, I am thinking about the following articles:

  1. Introduction to Lucene
  2. Indexing basics
  3. Search basics
  4. Alternatives ( did you mean …)
  5. Faceted search / Drill down
  6. Class reference

Let met know if you have got more ideas for articles.

Designing an Online Shopping Cart, an Architects Tale

February 16th, 2009 by

Webshop Cart

For my work at Liones I am writing a technical design for a shopping cart. The requirements are fairly basic, except for one: the shopping cart must be generic to support any payment service provider (psp) and customer relationship management (CRM) system. Also there might be several different product types in the future, like: subscriptions, downloads, pay per use, etc.. These requirements make the shop very complex and a great challenge.

I started with an investigation on the internet about this subject and I quickly found out that there aren’t much articles on this topic around, but I found a few very interesting ones though. Next I started to draw some UML diagrams; I added some best practices like the Money class.

Read the rest of this entry »

Todo: Read

June 10th, 2008 by

Today I received some new book which I have ordered, so I have something to do in the evening :P . I am not going to discuss every book in detail, I am just going to post a list of those books:

New Books

About ‘Beginning Python‘:
I just want to learn a different programming language and Python seems to be a good one. I think it is essential for a programmer to learn different languages so you are able to select the best tool for the job.

About ‘Scrum and XP from the Trenches‘:
At Liones we are currently starting with some projects using the Scrum project management methodology and I want to know about it.

Posted in Personal | No Comments »

Liones new office

May 29th, 2008 by

At the beginning of this week Liones moved to a new office and today I shot some photos so you can see how it look like. I don’t feel writing a lot of text about it I will rather let the photos do the talking.

Entrance
Visitors lounge
Our lounge room
My desk
Our meeting room
Posted in General | 2 Comments »