Saturday, May 11, 2013

Mobile Theme in Liferay

Now no need to do any nightmare work for creating mobile theme. No need to find User Agents and writting different CSS for different device. Single CSS will work for all device.

You are just few steps away for becoming expert in Mobile Theme.

NOTE :- Considering that you are aware of creating the Basic Theme in Liferay.

1) Create a Simple theme as we are creating for normal website portal(Make CSS code as percentage specific rather than Pixel specific for width Especially.).

2) While creating theme, Don't forget to add two most important things.
  •      In the portal_normal.vm, header section put the below line
    <meta name="viewport" content="target-densitydpi=160dpi, width=device-width, minimum-scale=1, maximum-scale=1">
  •      In the Script part add below line
     AUI().use('aui-viewport');

Above Two lines will handle your theme according to your device.

3) Complete your coding part that you required for creating the theme( Navigation , footer, etc).

4) Once the Development part is done from your end then you need to do the Configuration part for different device.  

5) Now no need to find user-Agent in Liferay with if and else conditions on the Code of theme. Liferay has solved that problem for us now. Liferay has introduced Mobile Device Rules which will do our work.

6) In order to make it compatible with different Devices like Iphone,Ipad,Android Devices you need to install plugins called WURFL.

 http://sourceforge.net/projects/lportal/files/Liferay%20Plugins/6.1.0%20GA1/wurfl-web-6.1.0.1-ce-ga1-20120106155615760.war/download

7)
Once You installed Plugins. Follow the below Video to create different rules for different devices.



8)
If you don't have device with you for testing then Install User-Agent Switcher in browser for Chrome and also for Firefox ( Required to restart the browser once you switch the User-Agent).

Thank You Guys for reading. Please post your comments and reviews.

Wednesday, January 2, 2013

Tabs with Search Container in Liferay

Generally we have to write a lot of javascript and java code in order to deal with paging in Web based application.

But with liferay you don't have to deal with that any more. Your life become easier with liferay.

As I used to post regularly in liferay forums. I found that most of the people face issues of pagination with Tabbing.
Here I would represent how search container works with Tabs.

Below are some of the screenshot for the demo that I am going to discuss in this post.







As you will refer above screenshot, you will be able to see two tabs and both of them having list of data.
First Tab show the list of all the User Group and the Second Tab shows the list of all Users for the Current Company.

Below are the steps you need to follow :-

1) First Create the Controller Class which will extend the MVC Controller and put it's Entry in the portlet.xml.

com.blog.demo.controller.SearContainerController

2) In order to create the Tabbing View, you have to write below code in your jsp page. So in my case I have created the view.jsp and whose entry by default set in the portlet.xml.

	









		
			
				
						<%@include file="/html/portlet/searchcontainer-with-tabs/tabs/usergroup.jsp" %>
			
			
		
		
			
			
					<%@include file="/html/portlet/searchcontainer-with-tabs/tabs/user.jsp" %>
			
			
		
		

 

usergroup.jsp

                
                
                    
					
                    
                    
                     
                  

                

       

user.jsp

                
                 
 
                    
 
     
     
 
     
  

                

       
NOTE :- Here on the basis of  "tabs" parameter, it will return the search container.

4) In order to make the code more readable, I created the seperate class for both the UserGroup i.e., UserGroupUtil and for User i.e.,UserUtil

UserGroupUtil
public class UserGroupUtil
{

    public static void searchContainerData(RenderRequest renderRequest,RenderResponse renderResponse)
    {
        List<usergroup> userGroupList = new ArrayList<usergroup>();
        Map<string tring="tring"> paramMap= new HashMap<string tring="tring">();

        paramMap.put("tabs", "UserGroup");

        PortletURL iteratorURL= renderResponse.createRenderURL();
        Iterator<map .entry=".entry" string="string" tring="tring">&gt; entries = paramMap.entrySet().iterator();
        while (entries.hasNext()) {
            Map.Entry<string string="string"> entry = entries.next();
            // System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());
            iteratorURL.setParameter(entry.getKey(), entry.getValue());
        }
        PortletConfig portletConfig = (PortletConfig)renderRequest.getAttribute(JavaConstants.JAVAX_PORTLET_CONFIG);
        ThemeDisplay themeDisplay = (ThemeDisplay)renderRequest.getAttribute(WebKeys.THEME_DISPLAY);
        SearchContainer<usergroup> searchContainer = new SearchContainer<usergroup>(renderRequest, null,
                null, SearchContainer.DEFAULT_CUR_PARAM, ParamUtil.getInteger(renderRequest,  SearchContainer.DEFAULT_DELTA_PARAM, 5),
                iteratorURL, null, LanguageUtil.get(portletConfig, themeDisplay.getLocale(), "No UserGroups were Found"));
        int total = 0;
        try {

            userGroupList=UserGroupLocalServiceUtil.getUserGroups(themeDisplay.getCompanyId());
            total = userGroupList.size();

        } catch (SystemException e) {
            SessionErrors.add(renderRequest, SystemException.class.getName());
        }
        userGroupList = ListUtil.subList(userGroupList, searchContainer.getStart(), searchContainer.getEnd());

        searchContainer.setTotal(total);
        searchContainer.setResults(userGroupList);
        renderRequest.setAttribute("userGroupSearchContainer", searchContainer);

    }
}


UserUtil
public class UserUtil
{

    public static void searchContainerData(RenderRequest renderRequest,RenderResponse renderResponse)
    {
        List<user> userList = new ArrayList<user>();
        Map<string tring="tring"> paramMap= new HashMap<string tring="tring">();

        paramMap.put("tabs", "User");

        PortletURL iteratorURL= renderResponse.createRenderURL();
        Iterator<map .entry=".entry" string="string" tring="tring">&gt; entries = paramMap.entrySet().iterator();
        while (entries.hasNext()) {
            Map.Entry<string string="string"> entry = entries.next();
            // System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());
            iteratorURL.setParameter(entry.getKey(), entry.getValue());
        }

        PortletConfig portletConfig = (PortletConfig)renderRequest.getAttribute(JavaConstants.JAVAX_PORTLET_CONFIG);
        ThemeDisplay themeDisplay = (ThemeDisplay)renderRequest.getAttribute(WebKeys.THEME_DISPLAY);
        SearchContainer<user> searchContainer = new SearchContainer<user>(renderRequest, null,
                null, SearchContainer.DEFAULT_CUR_PARAM, ParamUtil.getInteger(renderRequest,  SearchContainer.DEFAULT_DELTA_PARAM, 10),
                iteratorURL, null, LanguageUtil.get(portletConfig, themeDisplay.getLocale(), "No Users were Found"));
        int total = 0;
        try {

            userList = UserLocalServiceUtil.getCompanyUsers(themeDisplay.getCompanyId(), -1, -1);
            total = userList.size();

        } catch (SystemException e) {
            SessionErrors.add(renderRequest, SystemException.class.getName());
        }
        userList = ListUtil.subList(userList, searchContainer.getStart(), searchContainer.getEnd());

        searchContainer.setTotal(total);
        searchContainer.setResults(userList);
        renderRequest.setAttribute("userSearchContainer", searchContainer);

    }
}

In order to work pagging in proper way for search container with different tabs. We need to create the iterator URL in proper manner. Because Pagging in Search Container works based on IteratorURL. So we need to pass proper parameter in the Iterator URL. The Below code plays an key role in the Tabbing with Search Container.
Map<String,String> paramMap= new HashMap<String,String>();



        paramMap.put("tabs", "User");



        PortletURL iteratorURL= renderResponse.createRenderURL();

        Iterator<Map.Entry<String, String>> entries = paramMap.entrySet().iterator();

        while (entries.hasNext()) {

            Map.Entry<String, String> entry = entries.next();

            // System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());

            iteratorURL.setParameter(entry.getKey(), entry.getValue());

        }

In the above code I used HashMap, because if we have more parameter to pass then we can pass easily in the Iterator URL. Hope it will be useful !!!!

Monday, December 31, 2012

Integrating Solr with Liferay 6

Building Solr & Installing Solr instance on tomcat.
  1. Download Solr-1.3.0 release from Solr.
  2. Unzip .tar on some location. For eg. /opt/solr/
  3. Make /opt/solr/example/solr as a $SOLR_HOME.
  4. Copy apache-solr-1.3.0.war file from /opt/solr/dist and paste it into /opt/solr/example/solr.
  5. Open up the /opt/solr/example/solr/conf/solrconfig.xml
    Replace
    <dataDir>${solr.data.dir: ./solr/data}</dataDir>
    by following 
    <dataDir>${solr.data.dir:/opt/solr/example/solr/data}</dataDir>
    Note: The dataDir can also be temporarily overridden with the JAVA_OPTS environment variable  prior to starting Tomcat
             export JAVA_OPTS="$JAVA_OPTS -Dsolr.data.dir=/opt/solr/example/solr/data"
  1. It is recommended to run the Solr instance on separate tomcat instance other than liferay tomcat.
  2. So for separate tomcat for solr, consider it here. $SOLR_TOMCAT
  3. Into $SOLR_TOMCAT/conf/Catalina/localhost , create one solr.xml file and copy following content into the file and save it.
<?xml version="1.0" encoding="utf-8"?>
    <Context docBase="/opt/solr/example/solr/apache-solr-1.3.0.war"
                    debug="0" crossContext="true">

          <Environment name="solr/home" type="java.lang.String"
                value="/opt/solr/example/solr" override="true"/>

    </Context>
  1. Now start tomcat and check that it is running without any error or not.
Integrating Solr plugin with Liferay

  1. Download Solr plugin which is compatible with the Liferay version.
  2. Drop the plugin into $LIFERAY_HOME/deploy directory.
  3. Start liferay tomcat server. After started liferay tomcat, just stop both the tomcat servers (SOLR_TOMCAT and LIFERAY_TOMCAT).
  4. Openup the $LIFERAY_HOME/tomcat-6.0.18/webapps/solr-web/WEB-INF/classes/META-INF/solr-spring.xml
           for bean id=”solrServer” give the solar tomcat settings and save it.
           for eg. http://localhost:8181/solr
  1. Copy the $LIFERAY_HOME/tomcat-6.0.18/webapps/solr-web/WEB-INF/conf/schema.xml file and paste it into /opt/solr/example/solr/conf/ directory.


Congratulation, you have done!

Sunday, May 27, 2012

Dynamic Query in Liferay

Liferay provides several ways by which we can retrieve data from database. One of them is dynamic query. You can easily fire complex query using dynamic query and it will reduce overhead of creating custom finder methods. Lets go step by step with easy example. If you want to fire simple AND query then here is the example.
DynamicQuery dynamicQuery = DynamicQueryFactoryUtil.forClass(MyCustomTable.class);
dynamicQuery.add(PropertyFactoryUtil.forName("status").eq("Pending")
dynamicQuery.add(PropertyFactoryUtil.forName("userId").eq(10122);

Above query will search in table MycustomTable for records which has status as Pending and userId as 10122. If you want to sort your records in particular order that also you can do.
Order defaultOrder = OrderFactoryUtil.desc("modifiedDate");
Order secondOrder = OrderFactoryUtil.desc("requestId");
dynamicQuery.addOrder(defaultOrder);
dynamicQuery.addOrder(secondOrder);

Above query will order records based on Modified Date and RequestId. Now if you want to fire some complex query like combination of or , And , Between and Like then here is the example. By using RestrictionFactoryUtil we can file OR , AND , Like and Between query.
DynamicQuery dynamicQuery = DynamicQueryFactoryUtil.forClass(MyCustomTable.class);
 
Criterion criterion = null;
 
criterion = RestrictionsFactoryUtil.like("subject", StringPool.PERCENT + "Test Subject"+ StringPool.PERCENT);
 
criterion = RestrictionsFactoryUtil.and(criterion, RestrictionsFactoryUtil.between("create_date",10/02/2012,10/03/2012));
 
criterion = RestrictionsFactoryUtil.or(criterion , RestrictionsFactoryUtil.eq("status", "Pending"));
 
dynamicQuery.add(criterion); 

As you can see above query will try to fetch those records which has subject like "Test Subject" and its created_date is in between the above dates or the records which has status as pending. To execute dynamic query.
 
List requestList = MyCustomTableLocalServiceUtil.dynamicQuery(dynamicQuery);

Saturday, May 26, 2012

Deploying Ext in Liferay 6

On Deploying EXT, We face the problem that our changes are not getting reflected.

I seen people in liferay forums continuously asking for the same.

It is not perfect but will work in the case , if you can't execute the command ant direct-deploy and want to execute ant deploy command.

The following steps you have to follow in order to redeploy the EXT Portlet

My Portlet name is Alert-ext so I am referring with this name in the below steps :-

1) Stop the Server
2) put ext-redeploy-6.0.5.jar in tomcat-6.0.29/Webapps/ROOT/WEB-INF/lib/
3) Delete the Alert-ext portlet from the webapps folder if in case you are redeploying
4) Remove ext-Alert-ext-service.jar from the tomcat-6.0.29\lib\ext
5) Remove all the *-ext.xml from the path tomcat-6.0.29\webapps\ROOT\WEB-INF except struts-config-ext.xml
6) Remove all the jar file related to ext from the tomcat-6.0.29\webapps\ROOT\WEB-INF\lib except ext-redeploy-6.0.5.jar
7) Start the Server
8) Deploy the EXT Portlet
9) After that it will ask for rebooting the server once the EXT portlet is successfully deployed.
10) Now once again start the server.

Your EXT portlet will re-deployed successfully and all the changes will get Executed.

Hope it helps !!!

Connecting to different database using Liferay Service Builder

Generally we guys used to connect with the liferay default Database.
We also have requirement that Client wants there Data on Separate Schema or Separate DB.
But In Liferay how we can connect with different DB?

Don't Worry guys your problem is now solved.

Just Follow some steps as below :-

1) In Service.xml define the datasource, session-factory,transcation-manager within the Entity Definition as follows:-


 test

 

 ...... 
 ...... 
 

2) Create a new file ext-spring.xml under WEB-INF/src/META-INF dir.


 
  
  
 

 
  
  
 

 
  
  
   
    
     
    
   
  
 

   
  
 

 
  
 

 
  
  
  
 
 
 
  
   
    
   
        
     
    



Redirect to Static page in liferay within a single portlet

In Liferay most of time happens with us that after submitting the form we want to redirect it to some other page.

Now it's not difficult any more.

Please check below code.It will help you to redirect to the Static page as you are aspecting in liferay.
String portletName = (String)actionRequest.getAttribute(WebKeys.PORTLET_ID);

ThemeDisplay themeDisplay = (ThemeDisplay) actionRequest.getAttribute(WebKeys.THEME_DISPLAY);

PortletURL redirectURL = PortletURLFactoryUtil.create(PortalUtil.getHttpServletRequest(actionRequest),
portletName,
themeDisplay.getLayout().getPlid(), PortletRequest.RENDER_PHASE);

redirectURL.setParameter("jspPage", "your jsp path");

actionResponse.sendRedirect(redirectURL.toString()); 
Congratulations, You have DONE NOW !!!!!!!