Monday, June 13, 2011

Creating a Liferay Portlet From Google Web Toolkit

Yes, you can do it.

Now, I'm still in the process of refining the method but here's a quick and dirty approach. You just have to remember:
  • GWT applications "compile" Java source code into JavaScript.
  • Liferay Portlets have their JavaScript source files defined in the liferay-portlet.xml
Keep that in mind and you'll have no problems.

The Environment:
Liferay 6.06
Tomcat 6.0.29
Windows 7
Google Web Toolkit

*This should work on Liferay 5 as well but I haven't tried it.

First, if you're an experienced GWT developer then you already know how to build and compile your code. If you aren't, complete this tutorial first.

Once you've "compiled" your GWT project you'll need an empty Liferay portlet project to transplant your GWT project into. Go ahead and create one using the Liferay SDK.

Now that you have your empty Liferay portlet and your compiled GWT project, you have everything you need.

Suppose our project is called SuperPortlet.

  • Copy your war/WEB-INF/appengine-web.xml and war/WEB-INF/logging.properties files into the empty portlet's WEB-INF folder.
  • Copy your /SuperPortlet folder into the empty portlet's /docroot folder.
  • Copy your SuperPortlet.css and SuperPortlet.html files into the portlet's docroot folder.
  • Rename SuperPortlet.html to view.jsp
  • In your view.jsp file, there are a few tags that need to go away. In portlets we don't need <html>, <body>, <title> or <head> tags. Blow them away.
  • You don't need the <link> or <script> tags either. We're going to specify our .css and .js files elsewhere.
  • Add this to the top of your view.jsp file:

<%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>

<portlet:defineObjects />

  • Now, open your liferay-portlet.xml file.
  • In the <header-portlet-css> tag, add the path to the .css file. In this case the line would look like this:
<header-portlet-css>/SuperPortlet.css</header-portlet-css>

*Note: This assumes the .css file is in the /docroot folder. If you have a subfolder with your .css just put it there and be sure the path is defined correctly in the above tag.

  • This is the tricky part... The auto-generates portlet defines a <footer-portlet-javascript> tag. If you put the path to your SuperPortlet.nocache.js file in there, it won't work. You need to change "footer" to "header."
<header-portlet-javascript>/SuperPortlet/SuperPortlet.nocache.js</header-portlet-javascript>

Again, adjusting that file path depending on how you organize your portlet.

Be sure to copy over any images or other .css and .js files you have (defining each in its own separate tag in the liferay-portlet.xml file) and you should be ready to rock & roll. I did this in Eclipse and exporting the project to a .war file gave me a deployable .war that worked great.

5 comments:

  1. Hello, I am new to both GWT (2.3) and Liferay. I am hoping you could help.

    I have the correct versions of liferay and GWT. I have Eclipse Helios Java EE version. I have both GWT and liferay plugins for Eclipse.

    Within Eclipse, I have created a new GWT Web application that generates sample code to send your name to the server and the server sends back a response. I can run this fine in Eclipse.

    Then I created a new Liferay project. When doing so. it automatically creates a Portlet plugin. I can deploy this plugin into Liferay and it shows up fine.

    Now I am trying to follow your instructions
    ----
    Copy your war/WEB-INF/appengine-web.xml and war/WEB-INF/logging.properties files into the empty portlet's WEB-INF folder.
    ----
    My portlet's WEB-INF folder is populated with the sample portlet it created. Am I supposed to delete all the folder's and files under this WEB-INF directory?

    How did you create a Liferay project without creating a portlet?

    Thanks in advance!
    Brian

    ReplyDelete
  2. No, you don't want to blow those files away since those are your portlet configuration files. Just make sure that all the portlet id attributes are consistent. The only portlet template file you want to completely blow away is the template view.jsp since you're replacing it with your own.

    ReplyDelete
  3. What about client-side paths in IMG tags and javascripts? Portlet works in contextPath while browser page works in root path. None imaged buttons etc will work I guess.

    How to solve this problem?

    ReplyDelete
  4. This comment has been removed by the author.

    ReplyDelete
  5. In a portlet view page, use relative path names for image resources. For example, in one of my JSF 2.0 portlets, I use url="/css/liferay-images/close.png" in a graphicImage control.

    ReplyDelete