Showing posts with label liferay. Show all posts
Showing posts with label liferay. Show all posts

Wednesday, July 08, 2015

Creating Portlet URLs


Listed below are various ways to create portlet action and render phase URLs

Creating URL within/to the current portlet.

1. Using Taglib:

For Render URL

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

<portlet:renderURL var="myRenderURL1" windowState="<%=LiferayWindowState.NORMAL.toString()%>">
<portlet:param name="mvcPath" value="/html/view/myresponse.jsp"/>
</portlet:renderURL>

Similarly action URL looks like below
<portlet:actionURL var="myActionURL1" windowState="<%=LiferayWindowState.NORMAL.toString()%>">
<portlet:param name="cmd" value="update"/>
</portlet:actionURL>

2. Using Java code

For render URL
PortletURL myRenderURL2=renderResponse.createRenderURL();
myRenderURL2.setWindowState(LiferayWindowState.NORMAL);
myRenderURL2.setParameter("cmd", "view");
Similarly action URL looks like below
PortletURL myActionURL2=renderResponse.createActionURL();
myActionURL2.setWindowState(LiferayWindowState.NORMAL);
myActionURL2.setParameter("cmd", "update");

Creating URL outside the current portlet, that is URL to the other page or portlet.


PortletURL myRenderURL3= PortletURLFactoryUtil.create(request,  themeDisplay.getPortletDisplay().getId(), themeDisplay.getPlid(), PortletRequest.RENDER_PHASE);

 myRenderURL3.setWindowState(LiferayWindowState.NORMAL);
 myRenderURL3.setPortletMode(LiferayPortletMode.VIEW);
 myRenderURL3.setParameter("jspPage", "/season/rainy.jsp");

Here themeDisplay.getPortletDisplay().getId() is the id of the current portlet to be viewed or it can be the id of the other portlet to be viewed and themeDisplay.getPlid() is the page layout Id of the current page and can point to the plid of some other page on which the portlet is deployed.


Tuesday, June 30, 2015

Invoke custom portlet service using Java Reflection


Requirement:
Create a custom service 'myPojo' in a custom portlet named 'my-portlet'.
Access the above service in a Liferay jsp via hook.
This can be achieved by placing the service jar in the tomcat-lib but in certain scenarios where the access and deployment restrictions are applied and deployment does not allow to manually deploy the service jar to tomcat-lib below approach will be helpful.

Portlet name : my-portlet
Service Entity : MyPojo
Method to invoke: getMyPojo
Pojo property to read : _myField (exact name can be verified from the service generated model implementation class MyPojoModelImpl)




ClassLoader classLoader = PortletBeanLocatorUtil.getBeanLocator("my-portlet").getClassLoader();
Class clazz = classLoader.loadClass("com.informatick.hub.service.MyPojoLocalServiceUtil");
java.lang.reflect.Method method = clazz.getMethod("getMyPojo", long.class);
Object retunedObject = method.invoke(clazz.newInstance(), classPK);
    
java.lang.reflect.Field ouaField;
Class beanClass = retunedObject.getClass().getSuperclass().getSuperclass();
        
 ouaField = beanClass.getDeclaredField("_myField");
 ouaField.setAccessible(true);
 String tempString = (String) ouaField.get(retunedObject);

 long oua = 0;
 oua = GetterUtil.getLong(tempString);

 System.out.println("Returned vvalue : "+oua) 



Wednesday, April 30, 2014

Liferay : Advance Web Content Structures and Templates

The post details about the functionality to have multiple views for a web content article.

Currently only one view can be rendered for a article, but in real word scenarios there are occasions when different view are needed for the same content on same or different pages in Liferay.
Below are the steps with detailed code to achieve the above feature:

Step 1:
Create a new structure

<?xml version="1.0"?>

<root>
 <dynamic-element name="Name" type="text" index-type="" repeatable="false">
  <meta-data>
   <entry name="displayAsTooltip"><![CDATA[true]]></entry>
   <entry name="required"><![CDATA[true]]></entry>
   <entry name="instructions"><![CDATA[]]></entry>
   <entry name="label"><![CDATA[Name]]></entry>
   <entry name="predefinedValue"><![CDATA[]]></entry>
  </meta-data>
 </dynamic-element>
 <dynamic-element name="Address" type="text" index-type="" repeatable="false">
  <meta-data>
   <entry name="displayAsTooltip"><![CDATA[false]]></entry>
   <entry name="required"><![CDATA[true]]></entry>
   <entry name="instructions"><![CDATA[]]></entry>
   <entry name="label"><![CDATA[Address]]></entry>
   <entry name="predefinedValue"><![CDATA[]]></entry>
  </meta-data>
 </dynamic-element>
</root>



Step 2:
Create a new template


<p>
 <span style="font-size: 12px; ">
  <em><strong>Name: </strong>${Name.getData()}</em>
 </span>
</p>
<p>
 <span style="font-size: 12px; ">
  <em><strong>Address:</strong>${Address.getData()}</em>
 </span>
</p>




Step 3:
Create a web content based on structure and template created in step 1 and step 2. Populate some data in the web content.

Now our focus will be to create a new view for the content created in above in step 3

Step 4:
Thus create a new structure which will be dummy structure and fields here will not be relevant
<?xml version="1.0"?>

<root>
 <dynamic-element name="Dummy" type="text" index-type="" repeatable="false">
  <meta-data>
   <entry name="displayAsTooltip"><![CDATA[true]]></entry>
   <entry name="required"><![CDATA[true]]></entry>
   <entry name="instructions"><![CDATA[]]></entry>
   <entry name="label"><![CDATA[Dummy]]></entry>
   <entry name="predefinedValue"><![CDATA[]]></entry>
  </meta-data>
 </dynamic-element>

</root>





Step 5:
Create a new template, based upon structure creates in step 4, and will be considered as second view of the content created in step 3:

#set ($articleId = "10813")

#set ($renderUrl  = $request.render-url)
#set ($namespace = $request.portlet-namespace)
#set ($groupId = $getterUtil.getLong($groupId))

##
## Getting services
##
#set ($journalArticleService = 
 $serviceLocator.findService('com.liferay.portlet.journal.service.JournalArticleLocalService'))


#set ($article = $journalArticleService.getLatestArticle($groupId,$articleId))

<h3>Details</h3>
<br />
<table class="taglib-search-iterator">
 <tr class="results-header">
  <th class="col-1">Name</th>
  <th class="col-1">Address</th>
 </tr>
  
       #set ($document = $saxReaderUtil.read($article.content))
       #set ($root = $document.getRootElement())
       
       #set ($nameD = 
         $root.selectSingleNode(
           "dynamic-element[@name='Name']/dynamic-content"))
           
       #set ($addressD = 
         $root.selectSingleNode(
           "dynamic-element[@name='Address']/dynamic-content"))


   
      <tr class="results-row first">
       <td class="align-left col-1 valign-left">
       ${nameD.text}
       </td>

            <td class="align-left col-2 valign-middle">
           ${addressD.text}
       </td>

      </tr>
                   
</table>



Here $articleId is the article id of the content created in step 3.

Step 6:
Create a web content based on structure and template created in step 4 and step 5. The purpose of this content will be to display the data from the content created in step 3.


Liferay: Selecting multiple categories in Search portlet and Category Navigation portlet

Below is the original post which helps you to modify search and category navigation portlet and as a result user will be able to select multiple categories.

For more details go to:
http://liferaythought.wordpress.com/2013/04/30/selecting-multiple-categories/

Thursday, July 12, 2012

Liferay: Disable portlet border

Aim: Disable border for all portlets

Solution:

The easiest way to do this is using theme. Open liferay-look-and-feel.xml  add to it below line to achieve the purpose by default for all portlets.

<theme id="myTheme" name="myTheme">
       <settings>
            <setting key="portlet-setup-show-borders-default" value="false" />
        </settings>
</theme>

Monday, June 18, 2012

AUI: Refresh on popup close button

To referesh the parent window while closing a AUI pop in liferay, use the following code:
window.myDialog = new A.Dialog(
            {
     on: {
      close: function() {
      document.location.href='<%=oncloseURL%>';
     }

    },
                title: title,
                centered: true,
    resizable: false,
    draggable: false,
    modal: true,
    width: 800,
    height:550,
   
       
            }
        )

Friday, June 15, 2012

Inter Portlet Coordination with JSR 286

JSR 168 (Potlet 1.0) specification doesn't clearly suggest any mechanism for the inter-portlet communication i.e. communication between two portlets. This was regarded as one of the major short-comings for JSR 168. Though most of the vendors had their own extensions to JSR 168 for managing inter-portlet communication, use of any of those methods defeat the very purpose of JSR 168. In absence of any well defined sophisticated mechanism, JSR 168 developer had to rely upon either PortalContext or Application Scope of Session for sharing information between the protlets.

JSR 286 has come up with a well defined model to achieve inter-portlet communication. There are two primary ways by which inter-portlet communication can achieved as follows -

  1. public render parameters in order to share render state between portlets.
  2. portlet events that a portlet can receive and send.


There are pros and cons of each method. Though the biggest advantage with Portlet Events method is that an object can be passed from one portlet to another as opposed to merely "String" in case of "Public Render Parameters" method.

Below are the steps to get it going:

Step 1:

Open portlet.xml and add the following entries

<portlet-app ...>
<portlet> ... </portlet>
<public-render-parameter>
<identifier>user-id</identifier> <qname xmlns:x="http://abc.com/userId">x:userId</qname>

</public-render-parameter>

</portlet-app>

Note:
  1. A developer can declare a list of public paramters for a portlet application in portlet.xml.
  2. Parameter names are namespaced to avoid naming conflict.

Step 2:

Portlet must declare which public param they want to use. e.g.

After adding declaration portlet.xml will look something like this.

<portlet-app ......>
<portlet>
<portlet-name>test1</portlet-name> <display-name>test1</display-name>
........ ........

<supported-public-render-parameter> user-id</supported-public-render-parameter>
</portlet>
<public-render-parameter>
<identifier>user-id</identifier> <qname xmlns:x="http://abc.com/userId">x:userId</qname>

</public-render-parameter>

</portlet-app>

Note: 
  1. Public params are available in all lifecycle method like processAction , processEvent, render and serveResource.

Step 3: 

We can set render parameter in the processAction() method by using the defined public render parameter identifier as the key. e.g.

public void processAction(ActionRequest request, ActionResponse response)

throws IOException, PortletException {
 ........ 
response.setRenderParameter("user-id", userId);
 }

Step 4: 

A portlet can read public render parameter using follwing method

request.getPublicParameterMap()

Note: 
  1. Public render parameters are merged with regular parameters so can also be read using

request.getParameter(name) or request.getParameterMap()

Step 5: 

A portlet can remove a public render parameter by invoking following methods.

response.removePublicRenderParameter(name)

or

portletURL.removePublicRenderParameter(name) 

References

http://blog.xebia.com/2009/04/19/inter-portlet-coordination-with-jsr-286/

Tuesday, May 15, 2012

Liferay: Working with model listeners

What 

Model Listener - as the name specifies that there is some class that in continuously looking to a entity model in liferay. More technically its a call back class which is called when some operation happens on the model (operation can be add/edit/delete).

Model Listener

public interface ModelListener<T> {
 public void onAfterAddAssociation(Object classPK, String associationClassName, Object associationClassPK) throws ModelListenerException;

public void onAfterCreate(T model) throws ModelListenerException;

public void onAfterRemove(T model) throws ModelListenerException;

public void onAfterRemoveAssociation(Object classPK, String associationClassName,  Object associationClassPK) throws ModelListenerException;

public void onAfterUpdate(T model) throws ModelListenerException;

public void onBeforeAddAssociation(Object classPK, String associationClassName, Object associationClassPK) throws ModelListenerException;

public void onBeforeCreate(T model) throws ModelListenerException;

public void onBeforeRemove(T model) throws ModelListenerException;

public void onBeforeRemoveAssociation(Object classPK, String associationClassName, Object associationClassPK) throws ModelListenerException;

public void onBeforeUpdate(T model) throws ModelListenerException;
}
 

How

To implement own listener on some Model (for example User) yin your portlet you need:
<hook>
 <portal-properties>portal.properties</portal-properties>
</hook>
 
Make an entry in file WEB-INF/src/portal.properties to define hook for specific model:
value.object.listener.com.liferay.portal.model.User=my.hook.UserListener 

Implement class by inheriting it from BaseModelListener<T> in our case BaseModelListener<User> and implementing only
  method we want to call-back:

    public class GroupListener extends BaseModelListener<Group> {
@Override public void    onAfterUpdate(User u) throws ModelListenerException { // do something here } }



Thursday, March 29, 2012

End of Version Announcement for Liferay 5.2 EE

On February 29, 2012, Liferay announces the End of Version for Liferay 5.2 EE. The last date to order Liferay 5.2 EE (Last Ship Date) is May 31, 2012.

For more details see the original post

Saturday, August 20, 2011

Liferay >>> open Liferay popup in web content

This post is about the solution to the problem i faced in liferay where i need to open one or more Liferay styled modal popups from web content portlet or similarly from any other portlet. In my case the popup i need to open is that of feedback from user. The steps i took to get it working are:

  1. To start with add an anchor tag in the web content portlet on which you want to open up a feedback popup
    <a id="" class="feedback_popup"> Submit Feedback</a>

  2. Now you need to go to the theme/javascript folder and edit javascript.js file. Add to it the code

    jQuery(document).ready(
    function() {
    th_FeedbackPopup()
    }
    );

    function th_FeedbackPopup() {
    jQuery(document).find("a.feedback_popup").click(function() {
    var url = new Liferay.PortletURL.createRenderURL();
    url.setPortletId("FEEDBACK_1");
    url.setWindowState("exclusive");
    url.setPortletMode("view");
    url.setParameter("struts_action", "/ext/feedvack/view");
    var popup = Liferay.Popup({
    draggable:false,
    width:500,
    height:'auto',
    url:url.toString(),
    resizable:false,
    modal:true,
    title:'Submit Feedback',
    position:[250,20]
    });
    });
    }
    The idea behing javascript is to bind the click event of all anchor elements on page having class "feedback_popup" to open a modal popup. Make sure that you should bind the event based on class name and not on element id as a page can have multiple such elements.

Thursday, April 14, 2011

Optimize: Liferay Performance


Goal: Once you have your portal up and running, you may find a need to tune it for performance, especially if your site winds up generating more traffic than you'd anticipated. There are some definite steps you can take with regard to improving Liferay's performance. The aim is to bring together all the tuning tips and configuration at a single location for reference.
  1. Liferay Configuration
    1. ##Lucene Search
      #Set the following to true if you want to index your entire library 
      of files on startup.
       
      index.on.startup=false
    2. system.properties
       # The layout cache filter will cache pages to speed up page rendering for# guest users. See  ehcache.xml to modify the cache expiration time to live.
      com.liferay.portal.servlet.filters.layoutcache.LayoutCacheFilter=true
    3. Disable unneeded filters
      Liferay comes by default with 15 servlet filters enabled and running. It is likely that for your installation, you don't need them all. Two filters that you can disable without any impact are the Compression Filter and the Strip Filter. These filters are responsible for shrinking the size of the response (to save bandwidth). The Strip Filter removes whitespace from the response object, and the Compression Filter compresses it. This obviously requires some processing, and so disabling these two filters can enhance performance.
      To disable a servlet filter, simply comment it out of your web.xml file.
      If there is a feature supported by a servlet filter that you know you are not using, you can comment it out as well to achieve some performance gains. For example, if you are not using CAS for single sign-on, comment out the CAS Filter. If you are not using NTLM for single sign-ons, comment out the Ntlm Filter. If you are not using the Virtual Hosting for Communities feature, comment out the Virtual Host Filter. The fewer servlet filters you are running, the less processing power is needed for each request.

      There is a known optimilisation for LR 5.0+ Compression Filter
      <filter>
              <filter-name>Cache Filter - Resource CSS JSP</filter-name>
              <filter-class>com.liferay.portal.servlet.filters.cache.CacheFilter</filter-class>
              <init-param>
                  <param-name>url-regex-pattern</param-name>
                  <param-value>.+/(barebone|css|everything)\.jsp</param-value>
              </init-param>
              <init-param>
                  <param-name>pattern</param-name>
                  <param-value>2</param-value>
              </init-param>
          </filter>   
    4. HTML : Saves some 50Kb on every page but portlet look-feel modification is not possible for all (including (Omni)Admin)
      ## Portlet CSS Portlet
       # Set this to true to enable the ability to modify portlet CSS at runtime
       # via the Look and Feel icon. Disabling it can speed up performance.
      portlet.css.enabled=false

      #
      # Set this to false if the system does not use allow users to modify the
      # look and feel.
      #
      look.and.feel.modifiable=true
    5. Javascript: Not needed scripts could be expunged here. But the fattest of them all jQuery is needed almost always
      ## JavaScript
       # Set a list of JavaScript files that will be loaded programmatically in
       # /html/common/themes/top_js.jsp.
       #
       # The ordering of the JavaScript files is important. Specifically, all
       # JQuery scripts should go first.
       #
       # The Liferay scripts are grouped in such a way, that the first grouping
       # denotes utility scripts that are used by the second and third groups. The
       # second grouping denotes utility classes that rely on the first group, but
       # does not rely on the second or third group. The third grouping denotes
       # modules that rely on the first and second group.
       #
       javascript.files= .....
      Setting this will improve download time, but tweaks above are probably unused
       ## JavaScript
       # Set this property to true to load the combined JavaScript files from the
       # property "javascript.files" into one compacted file for faster loading for
       # production. Set this property to false for easier debugging for
       # development. You can also disable fast loading by setting the URL
       # parameter "js_fast_load" to "0".
       javascript.fast.load=true
    6. CSS: Set this property to true to load the theme's merged CSS files for faster loading for production.
      theme.css.fast.load=true
    7. Resources: Get your images and other resources from your personalised theme or even an HTTP server alias like www.liferay.org/resources/ Resources uploaded in Liferay are being served-up from database and will always be slower than using this strategy. especialy for recurring enterprise logo's and all.
    8. Themes: If you need a high performing landing-page and other pages you could consider creating a special theme for these pages.
    9. Velocity Caching: Set this to true in production so that VM templates are cached
      velocity.engine.resource.manager.cache.enabled=true
    10. CSS: Hack removing ALL CSS
      edit templates\portal_normal.vm;
       <head>
           #if ( $is_signed_in )
                #css ($css_main_file) 
           #end
       </head>
  2. Tomcat Configuration
  3. OS settings
  4. MySQL: Links to useful references:
        * A good sample my.cnf: http://www.theadminzone.com/forums/showthread.php?t=8150
        * Optmization, understanding mysql: http://www.mysqlperformanceblog.com/files/presentations/UC2005-Advanced-MySQL-Performance-Optimization.pdf
        * MySQL Performance Tuning Primer Script: http://day32.com/MySQL/
  5.  Memory:
    Memory is one of the first things to look at when you want to optimize performance. If you have any disk swapping, that will have a serious impact on performance. Make sure that your server has an optimal amount of memory and that your JVM is tuned to use it.
    There are three JVM command switches that control the amount of memory it will use.
    -Xms
    -Xmx
    -XX:MaxPermSize
    These three settings control the amount of memory available to the JVM initially, the maximum amount of memory into which the JVM can grow, and the separate area of the heap called Permanent Generation space. 
    Issues with PermGen space can also affect performance. PermGen space contains long-lived classes, anonymous classes and interned Strings. Hibernate, in particular—which Liferay uses extensively—has been known to make use of PermGen space. If you increase the amount of memory available to the JVM, you may want to increase the amount of PermGen space accordingly. 
  6. Portlets: Liferay comes pre-bundled with many portlets which contain a lot of functionality, but not every web site that is running on Liferay needs to use them all. In portlet.xml and liferay-portlet.xml, comment out the ones you are not using. While having a loan calculator, analog clock, or game of hangman available for your users to add to pages is nice, those portlets may be taking up resources that are needed by custom portlets you have written for your site. If you are having performance problems, commenting out some of the unused portlets may give you the performance boost you need.
  7. References/Source
    1. http://www.liferay.com/community/wiki/-/wiki/Main/Performance
    2. http://www.liferay.com/documentation/liferay-portal/5.1/administration/-/ai/performance-tuning;jsessionid=F9EDDE895FF685955600AF21B25C5D43.node-1

      But be careful, these settings need a powerful Application Server.
      Improvement: Approximately 50% faster
      Probably this works also with other Application Servers like Tomcat..
       

Wednesday, April 06, 2011

Liferay Facebook Portlet

http://code.google.com/p/liferay-facebook-portlet/

Liferay Cache

To use liferay cache their is a very good article available at :
http://rutvijshah.wordpress.com/2010/02/27/liferay-cache/

Thursday, March 17, 2011

Liferay Twitter portlet

https://code.google.com/p/liferay-twitter-portlet/

Friday, February 18, 2011

Liferay 6: Deployment/Undeployment with Ext plugins environment

I have always liked the concept of plug-in in Liferay but using the ext environment as plug-in in Liferay 6 seems to be a little bit painful and time taking. It will need you to restart tomcat a couple of times if you are working in service files. The original  post which i used here for reference documents everything.  I am copying it here so that i can recall it in future. However i am listing below the major steps followed in the original post.
  1. Stop the tomcat.
  2. Remove ext plug-in related jars in @temp folder of your tomcat instance @temp\liferay\com\liferay\portal\deploy\dependencies
  3. Remove ext plug-in related jars from ROOT/WEB-INF/lib/
  4. Remove xml for ext plug-in from ROOT/WEB-INF/
  5. Remove service jar from @tomcat/lib/ext related to plug-in
  6. Start tomcat  and deploy updated plug-in war while tomcat is running, You will see a message like  "You must reboot the server and redeploy all other plugin". 
  7. Now stop the tomcat and restart it again for the global jars to take effect. And you are ready to go
In the original post you will see the bat script which can be quite handy.