Pages

Wednesday, 24 December 2014

Defining custom Velocity Variables for Liferay Themes

There are number of predefined variables that can be accessed from with in the liferay theme. For elaborated list of those, below is the url

http://www.liferay.com/community/wiki/-/wiki/Main/Access+Objects+from+Velocity?_36_pageResourcePrimKey=2905717

Apart from those variables, if at all we end up needing a custom variable, which define a custom functionality/value as per the specific business need, we can define them in two places.

1. init_custom.vm. 

init.vm file, which is present in the liferay theme, contains all the liferay defined velocity variables. As a best practice, all the custom variables should be defined in the init_custom.vm file. 
This file allows you to override and define new Velocity variables.

#set($background_url = $theme_display.getThemeSetting('background-url'))

In the above example we are reading the background-url value provided by the user, while configuring the themes.

2. Setting the variables in request scope under attribute WebKeys.VM_VARIABLES

Create a hook, either Service Pre action or Login Post Action hook and inside your extended pre or post Action class, create a Map object with the key and value of the vm variables you want to insert, and then set that into the attribute under the key WebKeys.VM_VARIABLES. The variables added to the map are directly accessible in the Theme. This method provide more flexibility than the earlier one as there are no restrictions for defining the variables in this method.

Here is the code snippet for the same


Map< String, Object > vmVariables = ( Map< String, Object > ) request.getAttribute( WebKeys.VM_VARIABLES );

if ( vmVariables == null ) {
         vmVariables = new HashMap< String, Object >();
}
vmVariables.put("someVariable", "someValue");


request.setAttribute( WebKeys.VM_VARIABLES, vmVariables );

Now the variable added to the Map is directly accessible from with in the velocity template file in the theme.

For example it can be directly accessible from portal_normal.vm as below

<a id="siteLogo" class="logo $logo_css_class" href="$someVariable" title="#language("go-to") $site_name"/>


Tuesday, 22 July 2014

Access Objects from Velocity

Objects Available in Themes, Layouts, and CMS #

In the theme, layout templates and CMS Templates we load all the tools found in the com.liferay.portal.velocity.VelocityVariables insertHelperUtilities() method:
  • arrayUtil
  • browserSniffer
  • dateFormats
  • dateTool
  • dateUtil
  • escapeTool
  • expandoColumnLocalService
  • expandoRowLocalService
  • expandoTableLocalService
  • expandoValueLocalService
  • getterUtil
  • htmlUtil
  • httpUtil
  • imageToken
  • iteratorTool
  • journalContentUtil
  • languageUtil
  • unicodeLanguageUtil
  • listTool
  • localeUtil
  • mathTool
  • numberTool
  • paramUtil
  • portalUtil
  • portal
  • prefsPropsUtil
  • propsUtil
  • portletURLFactory
  • velocityPortletPreferences
  • randomizer
  • saxReaderUtil
  • serviceLocator
  • sessionClicks
  • sortTool
  • staticFieldGetter
  • stringUtil
  • timeZoneUtil
  • utilLocator
  • unicodeFormatter
  • validator
  • accountPermission
  • commonPermission
  • groupPermission
  • layoutPermission
  • organizationPermission
  • passwordPolicyPermission
  • portalPermission
  • portletPermission
  • rolePermission
  • userGroupPermission
  • userPermission
  • locationPermission

Objects Which Can Be Restricted From Access by CMS #

We call these restricted variables. They are restricted by adding them to the following portal property:
    #
    # Input a comma delimited list of variables which are restricted from the
    # context in Velocity based Journal templates.
    #
    journal.template.velocity.restricted.variables=serviceLocator
Following are the list of variables that can be restricted:
  • portalUtil
  • portal
  • prefsPropsUtil
  • propsUtil
  • velocityPortletPreferences
  • serviceLocator
  • sessionClicks
  • utilLocator
Now, on the issue of what other variables are accessible where.

Run Time Variables #

In each of the three contexts there are some "run-time" variables which are available only in those contexts.

Layout Templates #

The only additional runtime variable for layouts is:
  • processor

Themes #

  • request
  • portletConfig
  • renderRequest
  • renderResponse
  • xmlRequest
  • themeDisplay
  • company
  • user
  • realUser
  • layout
  • layouts
  • plid
  • layoutTypePortlet
  • scopeGroupId
  • permissionChecker
  • locale
  • timeZone
  • theme
  • colorScheme
  • portletDisplay
  • navItems
  • fullCssPath
  • fullTemplatesPath
  • init
  • portletGroupId
  • processor
  • taglibLiferay
  • theme
These are all objects are you might expect them to be... real
HttpServletRequest
, real User, etc...

CMS Templates #

The processing of a template is handled in such a way that it is not dependent on access to a real HttpRequest of any kind. Why? Because it's done WITHIN the service call. We do not allow our service layer objects to have an HttpRequest or HttpResponse of any kind as parameters. Thus, we can't add any of those NON-serializable objects like
HttpServletRequest
,
ThemeDisplay
,
PortletDisplay
,
PortletPreferences
, etc... As such we have the following variables:
  • xmlRequest
  • request
  • company
  • companyId
  • groupId
  • journalTemplatesPath
  • viewMode
  • locale
  • permissionChecker
  • randomNamespace

Variables defined in init.vm #

From Alimozzaman blog:
These are the default Liferay 6 theme variables defined in init.vm.
I was searching but did not get any link ,so I hope this will help lot of
people also around  the globe. If anything goes  wrong, pls make a comment
and also try to add something that will help people around us.

## ———- Common variables ———- ##

$theme_display
$portlet_display
$theme_timestamp
$theme_settings
$css_class
$layout
$page_group
$liferay_toggle_controls
$liferay_dockbar_pinned
$css_folder
$images_folder
$javascript_folder
$templates_folder
$full_css_path
$full_templates_path
$css_main_file
$js_main_file
$company_id
$company_name
$company_logo
$company_logo_height
$company_logo_width
$company_url

$user_id
$is_default_user
$user_first_name
$user_middle_name
$user_last_name
$user_name
$is_male
$is_female
$user_birthday
$user_email_address
$language_id
$w3c_language_id
$time_zone
$user_greeting
$user_comments
$user_login_ip
$user_last_login_ip
$is_signed_in
$group_id

## ———- URLs ———- ##
$show_add_content
$add_content_text
$add_content_url
$layout_text
$layout_url
$show_control_panel
$control_panel_text
$control_panel_url
$show_home
$home_text
$home_url
$show_my_account
$my_account_text
$my_account_url
$show_page_settings
$page_settings_text
$page_settings_url
$show_sign_in
$sign_in_text
$sign_in_url
$show_sign_out
$sign_out_text
$sign_out_url
$show_toggle_controls
$toggle_controls_text
$toggle_controls_url
$update_available_url

## ———- Page ———- ##

$the_title
$selectable
$is_maximized
$is_freeform

$page_javascript_1
$page_javascript_2
$page_javascript_3
$layout
$page = $layout
$is_first_child
$is_first_parent
$the_title
$is_portlet_page

$all_portlets
$column_1_portlets
$column_2_portlets
$column_3_portlets
$column_4_portlets
$column_5_portlets
$maximized_portlet_id
$typeSettingsProperties
$page_javascript_1
$page_javascript_2
$page_javascript_3
$community_name
$css_class
$my_places_portlet_url
$community_default_public_url
$community_default_private_url
$community_default_url
$the_title
$layouts
$pages

## ———- Navigation ———- ##
$nav_items
$has_navigation

## ———- Staging ———- ##
$show_staging
$staging_text
## ———- My places ———- ##
$show_my_places
$my_places_text

## ———- Includes ———- ##
$dir_include
$bottom_include
$bottom_ext_include
$content_include
$top_head_include
$top_messages_include

## ———- Date ———- ##
$date
$current_time
$the_year
 
 Sample Example 

Write the below code in init_custom.vm


#set ($userLocalService= $serviceLocator.findService("com.liferay.portal.service.UserLocalService"))
#set ($user = $userLocalService.getUserById($request.get("theme-display").get("user-id")))
#set ($emailAddress = $user.getEmailAddress())

 

To get the view write the below code in portal_normal.vm

 <h1>$emailAddress</h1>

I Hope this will help for you in feature.
 

Friday, 27 June 2014

AUI form validations


Liferay has provided default validations which you dont have to write any script in your file
These are the examples

You have to ADD this Taglib before creating the form

<%@ taglib uri="http://liferay.com/tld/aui" prefix="aui" %>

Example 1:
<aui:input name="firstName"  label="Name">
 <aui:validator name="required"/>
 <aui:validator name="alpha"/>
</aui:input>

 Explanation:
  required: Tells that user must fill this field
                                          message: This field is required
alpha :tells that user must enter alpha character i.e spaces between words are not allowed
                                           message: please enter alpha characters only.


Example 2:

<aui:input name="Name" value='' label="Name">
 <aui:validator name="alphanum"/>
</aui:input>
  Explanation: 
  alphanum :This will accept alphabets and numbers
                                             message:Please enter only alphanumeric characters.
                                         

  Example 3: 
<aui:input name="Address"  type="textarea" label="Name">
 <aui:validator name="required"/>
 <aui:validator name="maxLength">160</aui:validator>
<aui:validator name="minLength">5</aui:validator> 
</aui:input>
Explanation:   
 maxLength:tells that user has to enter less than 160 characters in textarea
                                               message:Please enter no more than 160 characters.
 minLength: tells the user to enter the minimum x characters
                                               message:Please enter at least 5 characters.                                   


  Example 4:
<aui:input name="date" label="Date of Birth">
 <aui:validator name="date"></aui:validator>
</aui:input>
Explanation:   
 date: tells to the user to enter the valid date
                                                  message:Please enter a valid date                    

  Example 5:
<aui:input name="age"  label="age">
<aui:validator name="number"></aui:validator>
<aui:validator name="max">35</aui:validator>
<aui:validator name="min">18</aui:validator>
 <aui:validator name="digits"></aui:validator>
</aui:input>
Explanation:   
number:Tells to the user to enter only numbers
                                                   message:Please enter a valid number
 max:Tells the user to enter the number not more than 35
                                                   message:Please enter a value less than or equal to35
 min:Tells the user to enter the number not less than 18
                                                  message:Please enter a value greater than or equal to18
 digits:Tells to user to enter only digits
                                                   message:Please enter only digits

 Example 6: EMAIL


<aui:input name="email" value='' label="Email">
 <aui:validator name="email"/>
</aui:input>  
Explanation:  
email:Tells to the user entered email is in valid format or not.
                                                message:Please enter a valid email address.

  Example 6: Password Checker
<aui:input name="password1" id="password1" label="Password">
 <aui:validator name="required"></aui:validator>
</aui:input>
<aui:input name="password2" label="Re Type Password">
 <aui:validator name="equalTo">'#<portlet:namespace />password1'</aui:validator>
</aui:input> 
  Explanation:
equalTo:Check for the password same or not
                                               message:Please enter the same value again.

Example :7
 Validator for uploading the files
   <aui:validator name="acceptFiles">'jpg,png,tif,gif'</aui:validator>
Tells that user have has to upload the files that are specified in validator
                                                 message: Please enter a value with a valid extension

Custom message:

 If you are not satisfied with the messages give by liferay fallow the below process for all the above examples

<aui:input name="name"  label="Age">
 <aui:validator  name="required"  errorMessage="You must fill this field" >
 <aui:validator name="maxLengtherrorMessage="you have entered more than 160 characters it should be less than 160" >160</aui:validator>
</aui:validator>
</aui:input>

 If you want to write your own conditions to your text field fallow the below process


<aui:input name="marks"  label="marks">
 <aui:validator  name="custom"  errorMessage="the student is failed" >
function (val, fieldNode, ruleValue) {
var result = false;
if (val >35) {
result = true;
}
return result;
}
</aui:validator>
</aui:input> 

Explanation: 
For custom validation you have to write your script function inside the validator tag as mentioned  above 





 

Saturday, 24 May 2014

Liferay Client Side Inter Portlet Communication Using Ajax


Objective:

Achieve inter portlet communication from client side using Ajax and Liferay Java Script.

Introduction:

Inter portlet communication is way of exchange the data between portlets in the page or portlets which reside in the other pages.

In liferay we have different ways we can achieve this one of the way is client side inter portlet communication.

Environment:

Liferay 6.2 +Tomcat 7.x+MySQL 5.1

Note:

The code will work for portal 6.2 version you can try for 6.1 too.



Portlet Screen:


Procedure for deploy portlet:

You can use war file and directly place in your portal deploy folder and test or you can also use source to deploy portlet.

Once portlet is deployed successfully you can see the portlet in sample category names as Sender Portlet and Receiver Portlet.

Usage Of Portlets:

Drag and Drop two portlet in same page and enter email address in sender portlet then click on send button as soon as you click you can see user details in receiver portlet.

Client Side Inter Portlet Communication (IPC):

Client Side Inter Portlet Communication is one of the ways in IPC   this can apply the portlet which reside in same page. Because Client side IPC will uses java script to communicate that’s why all portlet which participated in IPC need to be in same page.

Liferay already have some java script library to implement client side IPC in portlet 
development.

Here we have two types of portlets

Sender Portlet
Receiver Portlet

Sender Portlet:

Sender portlet will fire or trigger the event means it will initiate the sending message to other portlet.

Receiver Portlet

Receiver portlet is ready to take/listen the event from sender portlet as soon as sender portlet send the message then receiver portlet reactive the messages. Here one or more receiver portlet can be for one sender portlet.

The thing is we need to bind the receiver portlet with sender event. So that it can be listen the event as soon as sender sends the message.

Note:

All portlet which participate in client side IPC should be in same page and here page refresh will not be happened.

Assumption:

Assume we have sender and receiver portlet in page and sender will get some user data from server and the data will be pass to receiver portlet.

Sender portlet get the data from server it will use the Ajax call and once it will get the data then the data will be sending to receiver portlet using Client Side IPC with help of liferay java script implementation methods.
Register event in sender portlet as follows

Java script syntax
 Liferay.fire('eventName',{
                param1:paramValue1,
                param2:paramValue2
});
Example code as follows in sender portlet view.jsp
Liferay.fire('getUserData',{
              name: vinod
});
                 
                
Receive the event from Sender Portlet in receiver portlet as Follows

Java script syntax
Liferay.on('eventName',function(event) {
// write code to get the veluese that sent by sender portlet
});
Example code as follows in receiver portlet view.jsp
Liferay.on('getUserData',function(event) {
 alert('User Name:'+ event.name)
});
Implementation In development

The following are the steps to implement
  1. Create Two Liferay MVC portlets
  2. Make it <requires-namespaced-parameters/>   tag value to false in portlets
  3. Register Event in Sender Portlet
  4. Receive Event in Receive portlet

Note:

This is Client Side IPC events mechanism using java script and the portlet all are in same page.
Create Two Liferay MVC portlets

Create two Liferay MVC portlet from Liferay IDE with eclipse environment and decide Sender and Receiver portlets.

Make it <requires-namespaced-parameters/>   tag value to false in portlets

In liferay-portlet.xml file we need to make <requires-namespaced-parameters/>   tag value to false so that we can pass data in request using Ajax call.

This we need to make it false in spring portlet and when we use ajax as well.

If we make it false then only we can pass data to server using Ajax call.

The following is example for liferat-portlet.xml file as follows

<portlet>
<portlet-name>sender</portlet-name>
<icon>/icon.png</icon>
<instanceable>false</instanceable>
<requires-namespaced-parameters>false</requires-namespaced-parameters>
<header-portlet-css>/css/main.css</header-portlet-css>
<footer-portlet-javascript>/js/main.js</footer-portlet-javascript>
<css-class-wrapper>sender-portlet</css-class-wrapper>
</portlet>
Which portlet need Ajax interaction then we need to make it false to that portlet.

Register Event in Sender Portlet

Now we need register required even in Sender portlet so that it will send events to receiver portlets. This is complete java script implementation and we will use Liferay java script implementation.

Here we will get user information from server using jQuery Ajax call and once we get user data then we are sending to receiver portlet  using liferay java script implementation method i.e. Liferay.fire(----)
The following is example code in Sender Portlet view.jsp page

<%@page import="com.liferay.portal.theme.ThemeDisplay"%>
<%@ taglib uri="http://java.sun.com/portlet" prefix="portlet"%>
<%@ taglib uri="http://liferay.com/tld/aui" prefix="aui" %>
<%@ taglib uri="http://liferay.com/tld/theme" prefix="liferay-theme" %>
<%@ page import="com.liferay.portal.kernel.portlet.LiferayWindowState" %>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<portlet:defineObjects />
<liferay-theme:defineObjects />
<portlet:resourceURL var="getUserData">
</portlet:resourceURL>
<script>
$(document).on('ready',function(){
jQuery('#<portlet:namespace/>getUserByEmail').click(function(event) {
var emailAddessValue = jQuery('#<portlet:namespace/>emailAddess').val();
  $.ajax({
url:'<%=getUserData%>',
dataType: "json",
data:{emailAddess:emailAddessValue,
companyId:'<%=themeDisplay.getCompanyId()%>'
},
type: "get",
success: function(data){
Liferay.fire('getUserData', {userData:data});
},
beforeSend: function(){
//before send this method will be called
},
complete: function(){
//after completed request then this method will be called.
},
error: function(){
$('#userContent').html('<span style="color:red">Connection problems</span>');
}
});
});
});
</script>
<aui:form method="POST" action="<%=getUserData%>" >
<aui:input type="text" name="emailAddess"   id="emailAddess" label="Email Address"/>
<aui:button type="button" name="getUserByEmail" value="Send" id="getUserByEmail" />
</aui:form>
Receive Event in Receive portlet

Now we need to receive the even in receiver portlet. We already know sender send the message or event now we need to catch the message using Liferay.on(---) method.

Note:

We can have multiple receiver portlet for one sender portlet.

The following is complete code in receiver portlet view.jsp page

<%@ taglib uri="http://java.sun.com/portlet" prefix="portlet"%>
<%@ taglib uri="http://liferay.com/tld/aui" prefix="aui" %>
<%@ taglib uri="http://liferay.com/tld/theme" prefix="liferay-theme" %>
<portlet:defineObjects />
<style>
#userData td{
font-weight: bold;
width:200px;
border: 1px solid gary;
}
</style>
<script>
Liferay.on(
'getUserData',function(event) {
jQuery('#userInformation').empty();
jQuery('#errorInformation').empty();
if(event.userData.error!=null){
            jQuery('#errorInformation').html(event.userData.error);
}else{
var htmlString="<table id='userData'>"+
"<tr><td>User Id</td><td>"+event.userData.userId+"</td></tr>"+
"<tr><td>First Name</td><td>"+event.userData.firstName+"</td></tr>"+
"<tr><td>Last Name</td><td>"+event.userData.lastName+"</td></tr>"+
"<tr><td>Email Address</td><td>"+event.userData.emailAddress+"</td></tr>"+
"</table>";
jQuery('#userInformation').html(htmlString);
}
});
</script>
<div id="userInformation"></div>
<div id="errorInformation" style="color:red;font-weight:bold;"></div>
Important points:
  • Inter Portlet Communication (IPC) can be achieved in different ways and client side IPC is one of the way.
  • Client Side IPC is pure java script implementation so that It apply only the portlet which are in same page.
  • Liferay implemented some java script methods to implement Client Side IPC.
  • We used Ajax call to get data from server one we get the data we populated in other portlet using Client Side IPC.