Liferay and Coldfusion 9 Portlets… yes you can!
Over the past few months at work, I have been tasked with finding a solution to run a Portal / CMS system. I went through a number of CMS systems, and Portals, doing the research and trying to find the feature sets that we required. I ended up making numerous recommendations to my Director. In the end one stood apart from the rest (mainly due to request by my Director), and that was Liferay.
Not being a JAVA house, I somewhat scratched my head at the request before me, as Liferay is basically Java development and I don’t have a strong JAVA background. But I quickly learned that it does support things other than JAVA, however you still CANNOT get away from the fact that it is JAVA under the hood of it all, and you will be at one point in time forced to modify portlets or extend the default environment of Liferay (currently version 6 as I write this up).
So, what Liferay does support (at least what matters to me) is PHP, Groovy, and Coldfusion (as it turned out — read on…). PHP is supported and works pretty good, a developer could quite happily create PHP content driven Portlets with very little work. Groovy (something a few members of my team use — yes I know, java related) is also supported, and you can essentially create ‘Groovlets’ (Groovy portlets). But the real gem, is that Coldfusion 9 can create portlets, and those are compatible running on-top of JBOSS / Liferay.
Anyway, the important thing for me (and my team) is that Liferay 6 + Coldfusion = doable. To install Coldfusion under Liferay 6, you will need the following:
- Download Liferay 6 with JBOSS (latest CE, or buy the EE license)
- Download Coldfusion 9 (developer — free license — limited to 3 ips I believe, if you need to test)
- Compile Coldfusion 9 as a deployable WAR file (which you will have Liferay auto deploy for you).
Assuming you know how to deply something via Liferay, you should now have Liferay 6 w JBOSS running, and ColdFusion 9 deployed under all that as a WAR. You should be looking at the browser window that pops up (by default on a Windows system, if that is what you choose to develop on). The URL should be something like
http://localhost:8080/web/guest/
You can change that URL to
http://localhost:8080/cfusion/CFIDE/administrator/
and complete the standard ColdFusion setup (data sources, session sharing with JAVA, etc).
Once all that is setup, you can create your very own portlet, I will take the quick route to show you how to get started, there are many other settings / options to configure if you want to categorize / customize your portlet for Liferay use. I will probably write about some of those methods in the future depending on interest.
Ok, back to work. At this point we should have the following done:
- Liferay 6 with JBOSS running
- ColdFusion 9 under Liferay as a WAR file that was auto deployed (from the deploy folder)
- ColdFusion 9 administrator section reviewed and configured to your liking.
- Your default browser open with Liferay
Once all those are done, let us navigate to the folder that contains the root cfusion directory:
C:\liferay-portal-6.0.3\jboss-5.1.0\server\default\deploy\cfusion.war
Once inside that folder, we will go into WEB-INF and modify (or create if they do not exist) the following files:
- liferay-portlet.xml
- portlet.xml
- web.xml
Here is what you should have (we will make a Hello World portlet — surprise):
liferay-portlet.xml:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE liferay-portlet-app PUBLIC "-//Liferay//DTD Portlet Application 5.2.0//EN" "http://www.liferay.com/dtd/liferay-portlet-app_5_2_0.dtd"> <liferay-portlet-app> <portlet> <portlet-name>helloWorld</portlet-name> <use-default-template>true</use-default-template> </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>
portlet.xml:
<?xml version="1.0" encoding="UTF-8"?> <portlet-app xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd" version="1.0"> <portlet> <portlet-name>helloWorld</portlet-name> <display-name>Hello World</display-name> <portlet-class>coldfusion.portlet.ColdFusionPortlet</portlet-class> <init-param> <name>cfcName</name> <value>portlets.helloworld.hello</value> </init-param> <supports> <mime-type>text/html</mime-type> <portlet-mode>VIEW</portlet-mode> <portlet-mode>EDIT</portlet-mode> </supports> <portlet-info> <title>Hello World Portlet</title> </portlet-info> </portlet> </portlet-app>
portlets.helloworld.hello using dot notation (portlets / helloword are folders, and hello is our CFC file), we define the PATH to the portlet CFC here we will be putting our hello.cfc file into the location
C:\liferay-portal-6.0.3\jboss-5.1.0\server\default\deploy\cfusion.war\portlets\helloworld\
and inside that we place a blank text file hello.cfc (we will get to that in a bit).
web.xml:
... <servlet> <servlet-name>WSRPProducer</servlet-name> <servlet-class>coldfusion.bootstrap.BootstrapServlet</servlet-class> <init-param> <param-name>servlet.class</param-name> <param-value>org.apache.axis.transport.http.AxisServlet</param-value> </init-param> <load-on-startup>101</load-on-startup> </servlet> <servlet> <servlet-name>helloWorld</servlet-name> <servlet-class>com.liferay.portal.kernel.servlet.PortletServlet</servlet-class> <init-param> <param-name>portlet-class</param-name> <param-value>coldfusion.portlet.ColdFusionPortlet</param-value> </init-param> <load-on-startup>16</load-on-startup> </servlet> ... <servlet-mapping> <servlet-name>helloWorld</servlet-name> <url-pattern>/helloWorld/*</url-pattern> </servlet-mapping> ...
This file should definitely exist (if I recall correctly), you will need to put this snippet (above) just UNDER the servlet definition WSRPProducer. Also the entry requires two parts, the servlet definition, and the servlet-mapping (they CANNOT be together, per DTD definition), so you will need to have all your servlet definitions above your servlet-mappings (or it just won’t re-deploy cfusion).
Ok, phew, we got that done. If you have problems, email me, if I have time I might help you 😉
Next we need to create a small Hello World Portlet, so lets get back to our empty hello.cfc file that we put into
C:\liferay-portal-6.0.3\jboss-5.1.0\server\default\deploy\cfusion.war\portlets\helloworld\hello.cfc
hello.cfc:
<cfcomponent extends="CFIDE.portlets.ColdFusionPortlet"> <cffunction name="doView" returntype="void" output="true"> <cfargument name="renderRequest" type="any" required="true" hint="A javax.portlet.RenderRequest java object"> <cfargument name="renderResponse" type="any" required="true" hint="A javax.portlet.RenderResponse java object"> Hello World from ColdFusion inside Liferay !!!! <br/><br/> Running under Liferay hosted on JBOSS, this file will reflect updates immediately when modified. No need to compile or any other crud! </cffunction> <cffunction name="processAction" returntype="void" access="public" output="false" hint="Called by the portlet container to allow the portlet to process an action request."> <cfargument name="actionRequest" type="any" required="true" hint="A javax.portlet.ActionRequest java object"> <cfargument name="actionResponse" type="any" required="true" hint="A javax.portlet.ActionResponse java object"> </cffunction> <cffunction name="doHelp" returntype="void" output="true"> <cfargument name="renderRequest" type="any" required="true" hint="A javax.portlet.RenderRequest java object"> <cfargument name="renderResponse" type="any" required="true" hint="A javax.portlet.RenderResponse java object"> <h1>ColdFusion Help</h1> <p>This is a Help message for the Hello Portlet.</p> </cffunction> <cffunction name="doEdit" returntype="void" output="true"> <cfargument name="renderRequest" type="any" required="true" hint="A javax.portlet.RenderRequest java object"> <cfargument name="renderResponse" type="any" required="true" hint="A javax.portlet.RenderResponse java object"> <h1>ColdFusion Edit</h1> <p>This is a Edit message for the Hello Portlet.</p> </cffunction> <cffunction name="init" returntype="void" access="public" output="false" hint="Called by the portlet container to indicate to a portlet that the portlet is being placed into service."> <cfargument name="portletConfig" type="any" required="true" hint="A javax.portlet.PortletConfig java object"> <cflog text="In init of Hello World from ColdFusion portlet"> </cffunction> </cfcomponent>
With the above code, that should get you your first ColdFusion 9 portlet for Liferay. If you watch you log (cmd prompt window running while Liferay is active) it will show that cfusion reloaded with 1 portlet active, it should look like something below.
19:38:38,455 INFO [PortletHotDeployListener] 1 portlets for cfusion are available for use 08/02 19:39:14 INFO License Service: Flex 1.5 CF Edition enabled 08/02 19:39:14 INFO Starting Flex 1.5 CF Edition 19:39:14,503 INFO [[/cfusion]] ColdFusionStartUpServlet: ColdFusion: Starting application services 19:39:14,503 INFO [[/cfusion]] ColdFusionStartUpServlet: ColdFusion: VM version = 1.5.0_16-b02 08/02 19:39:14 Information [main] - Starting logging... 08/02 19:39:14 Information [main] - Starting license... 08/02 19:39:15 Information [main] - Invalid ColdFusion 9 license. 08/02 19:39:15 Information [main] - Invalid ColdFusion 9 license. 08/02 19:39:15 Information [main] - Developer Edition enabled
Once that is done, you will find your ‘Hello World’ portlet under the ‘Undefined’ catagory of ‘Adding’ portlets to the page under liferay. Enjoy! Happy CF9 Portlet’ing.
Questions? Leave a comment, I’ll try to get to it. I am assuming that you have some sense of using Liferay here, I am not going to train you how to use it, unless you pay me 😉