ZK Liferay Integration First Step for creating ZK Liferay Portlet
Hello Friends,
Welcome to CAPITAL CODE.
As per current IT market trends Liferay is world’s leading enterprise-class open source portal. At the same time ZK is a very popular framework for RIA Applications. ZK is a highly productive open source Java framework for building amazing enterprise web and mobile applications. One can develop the AJAX based RIA without knowing AJAX, Javascript and jQuery.
Here are the steps to integrate ZK Framework with Liferay to develop the RIA Portlets. I have used Liferay 6.1 CE and ZK 6.0.1 CE for this demo portlet.
1) You can refer this WIKI Link to setup Liferay IDE with Eclipse.
2) For installing ZK Studio for Eclipse ZK you can refer this link.
2) For installing ZK Studio for Eclipse ZK you can refer this link.
3) Create Liferay Portlet
- Create new Liferay project
- Select Liferay MVC portlet option and click on finish.
3) ZK related configurations
- Edit \WEB-INF\web.xml file.
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>ZK-Sample-portlet</display-name> <listener> <description> Used to cleanup when a session is destroyed</description> <display-name>ZK Session cleaner</display-name> <listener-class>org.zkoss.zk.ui.http.HttpSessionListener</listener-class> </listener> <servlet> <description>The ZK loader for ZUML pages</description> <servlet-name>zkLoader</servlet-name> <servlet-class>org.zkoss.zk.ui.http.DHtmlLayoutServlet</servlet-class> <init-param> <param-name>update-uri</param-name> <param-value>/zkau</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet> <description>The asynchronous update engine for ZK</description> <servlet-name>auEngine</servlet-name> <servlet-class>org.zkoss.zk.au.http.DHtmlUpdateServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>zkLoader</servlet-name> <url-pattern>*.zul</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>zkLoader</servlet-name> <url-pattern>*.zhtml</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>zkLoader</servlet-name> <url-pattern>*.svg</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>zkLoader</servlet-name> <url-pattern>*.xml2html</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>auEngine</servlet-name> <url-pattern>/zkau/*</url-pattern> </servlet-mapping> <session-config> <session-timeout>30</session-timeout> </session-config> <jsp-config> <taglib> <taglib-uri>http://java.sun.com/portlet_2_0</taglib-uri> <taglib-location> /WEB-INF/tld/liferay-portlet.tld </taglib-location> </taglib> </jsp-config> </web-app>
- Add below zk.xml file to /WEB-INF dir
<?xml version="1.0" encoding="UTF-8"?> <zk> <library-property> <name>org.zkoss.zul.progressbox.position</name> <value>center,center</value> </library-property> <library-property> <name>org.zkoss.zk.portlet.PageRenderPatch.class</name> <value>org.zkoss.zkplus.liferay.NonRootContextJQueryRenderPatch</value> </library-property> <library-property> <name>org.zkoss.zkplus.liferary.jQueryPatch</name> <value>1500</value> </library-property> <error-page> <exception-type>java.lang.Throwable</exception-type> <location>/zul/error.zul</location> </error-page> <session-config> <device-type>ajax</device-type> <timeout-message>Session timeout. Please reload the page.</timeout-message> </session-config> </zk>
- Update /WEB-INF/liferay-portlet.xml file as per given below
<?xml version="1.0"?> <!DOCTYPE liferay-portlet-app PUBLIC "-//Liferay//DTD Portlet Application 6.0.0//EN" "http://www.liferay.com/dtd/liferay-portlet-app_6_0_0.dtd"> <liferay-portlet-app> <portlet> <portlet-name>zk-sample</portlet-name> <icon>/icon.png</icon> <instanceable>true</instanceable> <header-portlet-css>/css/main.css</header-portlet-css> <header-portlet-javascript>/zkau/web/js/zk.wpd</header-portlet-javascript> <footer-portlet-javascript>/js/main.js</footer-portlet-javascript> <css-class-wrapper>zk-sample-portlet</css-class-wrapper> </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>
- Update /WEB-INF/portlet.xml as per given below
<?xml version="1.0"?> <portlet-app version="2.0" xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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>zk-sample</portlet-name> <display-name>Zk Sample</display-name> <portlet-class>com.liferay.zk.ZKPortlet</portlet-class> <init-param> <name>zk_page_view</name> <value>/zul/view.zul</value> </init-param> <init-param> <name>zk_page_edit</name> <value>/zul/edit.zul</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> <supported-locale>en</supported-locale> <portlet-info> <title>ZK Sample</title> <short-title>ZK Sample</short-title> <keywords>ZK Sample</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> </portlet-app>
4) Add below ZK libraries in /WEB-INF/lib directory
- zcommon.jar
- zel.jar
- zhtml.jar
- zk.jar
- zkbind.jar
- zkplus.jar
- zul.jar
- zweb.jar
- bsh.jar
- commons-fileupload.jar
- commons-io.jar
package com.liferay.zk; import java.io.IOException; import javax.portlet.PortletException; import javax.portlet.PortletPreferences; import javax.portlet.PortletRequestDispatcher; import javax.portlet.PortletSession; import javax.portlet.RenderRequest; import javax.portlet.RenderResponse; import org.zkoss.zk.ui.Session; import org.zkoss.zk.ui.http.DHtmlLayoutPortlet; import com.liferay.portal.kernel.util.WebKeys; import com.liferay.portal.theme.ThemeDisplay; /** * The Class ZKPortlet. */ public class ZKPortlet extends DHtmlLayoutPortlet{ public static final String ZK_EDIT_PAGE = "zk_page_edit"; public static final String ZK_VIEW_PAGE = "zk_page_view"; private String strViewModePage; private String strEditModePage; public void init() { this.strViewModePage = getInitParameter(ZK_VIEW_PAGE); this.strEditModePage = getInitParameter(ZK_EDIT_PAGE); } @Override protected boolean process(Session sess, RenderRequest request, RenderResponse response, String path, boolean bRichlet) throws PortletException, IOException { setupSessionParameters(sess, request); return super.process(sess, request, response, path, bRichlet); } protected void setupSessionParameters(Session sess, RenderRequest request) { ThemeDisplay themeDisplay = (ThemeDisplay) request.getAttribute(WebKeys.THEME_DISPLAY); PortletSession portletSession = request.getPortletSession(); PortletPreferences prefs = request.getPreferences(); sess.setAttribute("SESSION_ID", portletSession.getId()); sess.setAttribute("THEME_DISPLAY", themeDisplay); sess.setAttribute("GROUP_ID", themeDisplay.getScopeGroupId()); sess.setAttribute("PORTLET_PREFERENCES", prefs); sess.setAttribute("PORTLET_ID",themeDisplay.getPortletDisplay().getId()); sess.setAttribute("currentUser",themeDisplay.getUser().getScreenName()); } @Override protected void doEdit(RenderRequest request, RenderResponse response) throws PortletException { try{ if (this.strEditModePage != null) { this.dispatch(this.strEditModePage, request, response); } else { this.doView(request, response); } } catch (IOException ex){ //Exception Handling Code } } @Override protected void doView(RenderRequest request, RenderResponse response) throws PortletException { try{ if (this.strViewModePage != null) { this.dispatch(this.strViewModePage, request, response); } } catch (IOException ex){ //Exception Handling Code } } protected void include(String path, RenderRequest renderRequest, RenderResponse renderResponse) throws IOException, PortletException { try{ PortletRequestDispatcher portletRequestDispatcher = getPortletContext().getRequestDispatcher(path); if (portletRequestDispatcher != null) { portletRequestDispatcher.include(renderRequest, renderResponse); } } catch (IOException ex){ //Exception Handling Code } } private void dispatch(String page, RenderRequest request, RenderResponse response) throws IOException, PortletException { PortletRequestDispatcher objDisp = this.getPortletContext().getRequestDispatcher(page); if (objDisp != null){ objDisp.include(request, response); } } }
6) Create /docroot/zul folder and place below zul files in it.
- view.zul
- edit.zul
- error.zul
view.zul
<?page id="viewPage" title="ZK Sample View Page" cacheable="false" language="xul/html" zscriptLanguage="Java" contentType="text/html;charset=UTF-8"?> <zk xmlns="http://www.zkoss.org/2005/zul" xmlns:zk="http://www.zkoss.org/2005/zk"> <window id="winView" width="100%"> <caption label="CAPITAL CODE"/> <grid> <auxhead> <auxheader label="ZK Liferay Portlet Window" colspan="2"/> </auxhead> <columns> <column label="Component Type" width="150px" /> <column label="Component"/> </columns> <rows> <row> <label value="Textbox Field" width="150px" /> <textbox width="150px" tabindex="1" constraint="no empty" /> </row> <row> <label value="Password Field" width="150px" /> <textbox type="password" width="150px" tabindex="2" /> </row> <row> <label value="Intbox Field" width="150px" /> <intbox width="150px" tabindex="3" /> </row> <row> <label value="Decimalbox Field" width="150px" /> <decimalbox format="###.##" width="150px" tabindex="4" /> </row> <row> <label value="Datebox Field" width="150px" /> <datebox format="yyyy/MM/dd" width="150px" tabindex="5"/> </row> <row> <label value="Listbox Field" width="150px" /> <listbox mold="select" tabindex="6"> <listitem label="Default" value="" /> <listitem label="CAPITAL CODE Java" value="java" /> <listitem label="CAPITAL CODE ZK" value="zk" /> <listitem label="CAPITAL CODE Liferay" value="liferay" /> </listbox> </row> <row> <label value="Spinner Field" width="150px" /> <spinner constraint="no negative,no zero" value="10" tabindex="7" /> </row> <row> <cell colspan="2" style="text-align:center"> <button mold="os" label="Submit" width="100px" height="30px" /> </cell> </row> </rows> </grid> </window> </zk>
edit.zul
<?page id="editPage" title="ZK Sample Edit Page" cacheable="false" language="xul/html" zscriptLanguage="Java" contentType="text/html;charset=UTF-8"?> <zk xmlns="http://www.zkoss.org/2005/zul" xmlns:zk="http://www.zkoss.org/2005/zk"> <window id="winEdit" width="100%" height="100px"> <caption label="CAPITAL CODE"/> <grid> <columns> <column label="ZK Liferay Portlet Window (EDIT)"/> </columns> <rows/> </grid> </window> </zk>
error.zul
<?page id="errorPage" title="ZK Sample Error Page" cacheable="false" language="xul/html" zscriptLanguage="Java" contentType="text/html;charset=UTF-8"?> <zk xmlns="http://www.zkoss.org/2005/zul" xmlns:zk="http://www.zkoss.org/2005/zk"> <window id="winError" width="100%" height="100px"> <caption label="CAPITAL CODE"/> <grid> <columns> <column label=" ZK Liferay Portlet Window (Error)"/> </columns> <rows/> </grid> </window> </zk>
Finally our Liferay Portlet will look like below,
After completing all above steps,
- Start the tomcat server in liferay.
- Deploy the portlet using ant deploy command.
- Login to the liferay and add the zk sample portlet in any page.
That's it. We are done with the demo of Liferay ZK Portlet. :)
Very nice blog and good help for setting up environment to develop portlet using zk.
ReplyDeletewhat is mean by Deploy the portlet using ant deploy command.
ReplyDeleteI followed this tutorial and it worked nicely. Thanks and keep up the good work.
ReplyDeleteMJ
Awesome, this topic is very useful for me
ReplyDeletemysql services
informative post.it is very useful post i really like this post.
ReplyDeletephp
Nice and help full post.....
ReplyDeletei have getting one error when i try to deploy the zk project in liferay 6.2..... error log is given below please suggest me how to resolve this one
SEVERE: Exception thrown by attributes event listener
java.lang.NoClassDefFoundError: org/zkoss/util/resource/XMLResourcesLocator
at org.zkoss.zk.ui.http.HttpSessionListener23.attributeRemoved(HttpSessionListener23.java:96)
at org.apache.catalina.core.ApplicationContext.removeAttribute(ApplicationContext.java:782)
at org.apache.catalina.core.ApplicationContextFacade.removeAttribute(ApplicationContextFacade.java:410)
at com.liferay.portal.kernel.deploy.hot.BaseHotDeployListener.unregisterClpMessageListeners(BaseHotDeployListener.java:155)
at com.liferay.portal.deploy.hot.PortletHotDeployListener.doInvokeUndeploy(PortletHotDeployListener.java:550)
at com.liferay.portal.deploy.hot.PortletHotDeployListener.invokeUndeploy(PortletHotDeployListener.java:140)
at com.liferay.portal.deploy.hot.HotDeployImpl.fireUndeployEvent(HotDeployImpl.java:111)
at com.liferay.portal.kernel.deploy.hot.HotDeployUtil.fireUndeployEvent(HotDeployUtil.java:31)
at com.liferay.portal.kernel.servlet.PluginContextListener.fireUndeployEvent(PluginContextListener.java:169)
at com.liferay.portal.kernel.servlet.SecurePluginContextListener.fireUndeployEvent(SecurePluginContextListener.java:294)
at com.liferay.portal.kernel.servlet.PluginContextListener.doPortalDestroy(PluginContextListener.java:132)
at com.liferay.portal.kernel.util.BasePortalLifecycle.portalDestroy(BasePortalLifecycle.java:31)
at com.liferay.portal.kernel.servlet.PluginContextListener.contextDestroyed(PluginContextListener.java:97)
at org.apache.catalina.core.StandardContext.listenerStop(StandardContext.java:4980)
at org.apache.catalina.core.StandardContext.stopInternal(StandardContext.java:5626)
at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:232)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:160)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:901)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:877)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:633)
at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:1113)
at org.apache.catalina.startup.HostConfig$DeployDirectory.run(HostConfig.java:1671)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
at java.util.concurrent.FutureTask.run(FutureTask.java:166)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)
Caused by: java.lang.ClassNotFoundException: org.zkoss.util.resource.XMLResourcesLocator
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1714)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1559)
... 28 more
11:45:26,783 INFO [localhost-startStop-6][PortletHotDeployListener:558] 1 portlet for ZK-Demo-portlet was unregistered
Jun 05, 2014 11:45:26 AM org.apache.catalina.core.ApplicationContext log
INFO: Closing Spring root WebApplicationContext
11:45:26,788 INFO [localhost-startStop-6][PluginPackageUtil:1016] Reading plugin package for ZK-Demo-portlet