Wednesday, May 6, 2015

[Liferay] Writing Custom Sql for multiple tables in Liferay

Hi Friends,

There were a number of times you might have faced a situation when you need data from multiple tables. Sometimes you would have got the data from one service, extract some data and then call another service, extract some more data and do the processing by writing some logic. Well, this has a major impact on performance and that's not good.

That's not good choice because you can write your own custom SQL query and get the desired result. The query we are writing, we always have a chance to optimize it and boost/improve performance. Alright, enough of the lecture.. lets get to work.

Friday, May 1, 2015

[Liferay][iPad][iPhone] Safari turns numbers into links

There are many calling applications which install some kind of plugin to turn numbers to links on which if you click will offer you to call. Skype's click to call is one of such application.

Well Safari, by default does this. We did not like it. You also don't, probably that's why you're here.. Here is the solution.

Open the theme or template or html file and add this meta tag.

<meta name="format-detection" content="telephone=no">

This will leave all numbers as it is. Now, you may also want to show some phone numbers as link which were actually phone numbers. In this case use like this.

<p>My phone number: <a href="tel:1-203-203-2020">1-203-203-2020</a></p>

This will show the phone number as link.

In case of liferay, open your theme's portal_normal.vm file and add the meta tag as mentioned above.

Hope this helps.

Tuesday, April 7, 2015

[Liferay] Access Liferay Services in Theme or Web Content using Velocity

Sometime, we need to get some data in our web contents. Well, using velocity, we can get the data we want. Create a simple structure and a template. You can assign that structure to some web content later.

Make sure your template script is VM. The below lines of code are for reference, they should help you to get the actual requirement done.

To get namespace of the portlet,
#set ($namespace = $request.get('portlet-namespace'))

To get company id
#set($companyId = $getterUtil.getLong($request.get("theme-display").get("company-id")))

In the line above you also get themeDisplay which can get you many more things. We have $request object here.

To get user service we can use $serviceLocator.
#set($userLocalService = $serviceLocator.findService("com.liferay.portal.service.UserLocalService"))

If you're unable to get $serviceLocator check portal-ext.properties for the property below and set accordingly.

# Set a comma delimited list of variables the Velocity engine cannot
# have access to. This will affect Dynamic Data List templates, Journal
# templates, and Portlet Display templates.
#
velocity.engine.restricted.variables=serviceLocator

Get user from the service
#set($user = $userLocalService.getUserByScreenName($companyId, "kravigupta"))

Get phone service
#set($phoneLocalService = $serviceLocator.findService("com.liferay.portal.service.PhoneLocalService"))

Get all phone numbers of user
#set($userPhones = $phoneLocalService.getPhones($companyId, "com.liferay.portal.model.Contact", $user.getContact().getContactId()))

You can even use validator
#if($validator.isNull($user))
<div>The user is null.</div>
#end

Hope this helps.


Thursday, April 2, 2015

[Iframe] X-Frame-Options : website does not permit framing


One of my friends, working on a project wanted to load another website in an iframe. But kept getting error similar to

Load denied by X-Frame-Options: http://some-website.com/dashboard/home does not permit framing. 

There is a meta tag for HTML that you can include which prevents embedding your site on other sites. For example Someone might use this blog on their own site using iframe. If I want that anyone can embed this site, I could use the meta tag below.

<meta http-equiv="X-Frame-Options" content="allow">

As explained by Mozilla.

The X-Frame-Options HTTP response header can be used to indicate whether or not a browser should be allowed to render a page in a <frame>, <iframe> or <object> . Sites can use this to avoid clickjacking attacks, by ensuring that their content is not embedded into other sites.

X-Frame-Options can have three values - DENY, SAMEORIGIN, ALLOW-FROM uri. The values explain themselves very well.

To configure this on Apache modify configuration ( httpd.conf )as below -

Header always append X-Frame-Options SAMEORIGIN

In case you do not have access to httpd.conf file.. you can also use .htaccess as below-

Header append X-FRAME-OPTIONS "SAMEORIGIN"

Well, that was fun :) we'll learn more on clickjacking more in another post.. stay tuned.

Until next time.

Ref : https://developer.mozilla.org/en-US/docs/Web/HTTP/X-Frame-Options

Wednesday, March 18, 2015

[Liferay] Get HTTPServletRequest in portlet

Hello Friends,

In case you submitted need HttpServletRequest in your portlet, here is the code snippet.

HttpServletRequest request = PortalUtil.getHttpServletRequest(renderRequest);
HttpServletRequest originalServletRequest= PortalUtil.getOriginalServletRequest(request);

This goes all the way from your custom code to  PortalImpl  and then PortletRequestImpl to get the request.

After getting request object it goes to find originalServletRequest.


This will be useful when you submitted your form or link without a proper portlet request or want to read a parameter from url.

Hope this helps.

Wednesday, March 4, 2015

[Liferay] Get URL using Portlet ID

Hi,

Sometimes, we need to get url based on portlet id. All we have is a portlet, we can easily get portlet id and then find the page where it is added.

To generate a url like this, we need PortletRequest, portletId, plid, and phase of the portlet.

plid is layout id which can be get like this..

long plid = PortalUtil.getPlidFromPortletId(themeDisplay.getScopeGroupId(), true, portletId); 

In case you don't know how to get themeDisplay,

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

Second argument to method is true which shows that this is private layout. In case of public layoue make it false. We already have portletId. 

We now have plid. Phase of the portlet is as per the requirement, assuming it is render phase for us. So once we have all the things. We call PortletURLFactoryUtil and create the url ( PortletURL )- 

PortletURLFactoryUtil.create(request, portletId, plid, PortletRequest.RENDER_PHASE);

That's it. Hope this helps.
Until next time.