Archive for the ‘Liferay’ Category

Jquery paginator for Liferay 6.1

This tutorial tells you how to make a custom jquery paginator in your liferay portlet.
This example is about photoalbums, but the page can contain whatever in the <div “image”>

The jquery file is specified in header-portlet tag in the liferay-portlet.xml :

<header-portlet-javascript>/js/jquery-1.8.3.js </header-portlet-javascript>

or in the jsp directly (as you can see below)

The code in the ViewPhotos.jsp is:

<script type="text/javascript" src="${renderRequest.contextPath}/js/jquery-1.8.3.js"></script>

 images = ImageLocalServiceUtil.getAllImagesbyAlbumId(albumId);
	String albumName= (String) request.getAttribute("albumName");
<div id="<portlet:namespace/><br />"><span style="color: blue;">Photogallery DEMO Version 0.X </span> 

<script type="text/javascript">
 var $jq = jQuery.noConflict(true); 
 }); </script>

<div id="wrapper-content">
<h2>Photo album Paginator</h2>

<div class="pagination">
 <li><a href="#" id="prev"><button>Previous</button></a>
 <li><a href="#" id="next"><button>Next</button></a></li>

<div id="content">
 No images found.
<div class="image">

 <img class="center" src="/<%=albumName=>/<%=path%>" alt="" width="40%" />


</div> <!--  content -->
</div> <!--  wrapper-content -->
</div>  <!--  portletnamespace -->

Remember to wrap it all with :  <strong><div id=”<portlet:namespace/>”></strong>

In my demo the “albumName” folder specified in the image attribute src is set in the xml file:

The content of the xml file is something the following:

<?xml version=”1.0″ encoding=”UTF-8″?>
<Context path=”/albumName” docBase=”/home/laura/albums/albumName” reloadable=”true”/>

albumName” might be something like “birthday_Party_Laura_2013

the jquery plugin (that I’ve placed in the main.js file) is the following:

(function($) {

	// Attach a new method to jQuery
		// PluginName - Pagination
		Pagination : function(options) {
			// Set the default values, use comma to separate the settings,
			// example:
			var defaults = {
					fadeSpeed : 100

			// options can be extended when the plugin is invoked
			var options = $.extend(defaults, options);

			// Creating a reference to the object
			var objContent = $(this);

			// child div of the "content" one
			var imageDivList = new Array();
			var lastPage = 1;
			var paginatedPages;

			// initialization function
			init = function() { // for each div
				$('.image').each(function() {

				// objContent.children().hide();

				// show first page (lastPage=1)

				// draw controls

			}; // end init function

			// show page function
			showPage = function(page) {
				i = page - 1;
				if (imageDivList[i]) {
					// hiding old page, display new one
					lastPage = i;


			// show pagination function (draw switching numbers)
			showPagination = function(numPages) {
				var pagins = '';
				for ( var i = 1; i <= numPages; i++) {
					pagins += '<li><a href="#" onclick="showPage(' + i
							+ '); return false;"><button>' + i + '</button></a></li>';
				} //     
				// after the firt element, with id="prev", append the list with
				// the page number links
				$('.pagination li:first-child').after(pagins);

			// perform initialization

			// and binding 2 events - on clicking to Prev
			$('.pagination #prev').click(function() {
			// and Next
			$('.pagination #next').click(function() {
				showPage(lastPage + 2);

	// pass jQuery to the function,

The css for the paginator buttons, that I have specified in the main.css file is:

ul, li {
    list-style-type: none;

.pagination {
    clear: both;
  /* width:250px; */

.pagination li {
        margin-left: 0 auto;

SSH: key generation and connection with different port number

Lately I’ve purchased a virtual private server hosting (VPS) to deploy my liferay portal. I’ve been assigned a different port number… and I needed to understand the steps to make a ssh connection.
After some hours surfing the web and making experiment, I could make it. So now I’m posting this litte tutorial, for those that want to work by the linux shell B)

Firt of all you need to generate a public and private keys with a cryptographic algorithm:

ssh-keygen -t dsa

I’ve chosen the DSA (digital signature algorithm), but you can choose RSA, etc.

After entering the ssh-keygen command on the shell, under the folder  ~/.ssh/ you will find the following files: id_dsa,, authorized_keys and known_hosts files.

Make sure that you have all the permissions on the folder and that you’re the only one that can read and write the authorized_keys file:

sudo chmod 600 ~/.ssh/authorized_keys

The system will add your host to the lists of the “known hosts”, when you try to login to the remote server for the first time.

Once your keys have been generated, you need to copy the public key in the “authorized_keys” file:

cp ~/.ssh/ ~/.ssh/authorized_keys

Then you need to send your public key to the server. Let’s assume that our ssh port number is 12345:

scp -P 12345 ~/.ssh/  [email protected]:~/.ssh/authorized_keys

The shell will ask you a password:

[email protected]'s password: user's passowrd

Now that you’ve sent your public key to the server you can connect:

ssh -p 12345 [email protected]

After this command you’ll be asked your passphrase password (that you set when you generate the public key),
so you can be authenticated with your private key.

That’s it! 😎

Liferay search container pagination problem when passing form parameter SOLVED

Hello, guys!
I’ve been struggling for a couple of days trying to make my seach container pagination works.
When you clicking on the next page and you need to use a form parameter value submitted to get the rows, you need to store it in the portlet preferences, otherwise you lose it in the page “refresh”.

I haven’t found a solution on the web so far, so I’m posting my code snippets… that WORKS lol:
but I’m using portlet preferences … check it out!

[b]action method in the controller:[/b]

		public void searchVolume(ActionRequest request, ActionResponse response)
			throws IOException, PortletException, PortalException,
			SystemException, NoSuchVolumeException {

		String volumeIdentifier = request.getParameter("volumeId");
		long volumeId = (long) Integer.parseInt(volumeIdentifier);
		long idVol = 0;

		boolean found = false;
		boolean emptyList = false;

		List volume = new ArrayList();
		volume = VolumeLocalServiceUtil.getAllVolumes();
		List caseArchive = new ArrayList();
		caseArchive = CaseArchiveLocalServiceUtil

		if (caseArchive.size() == 0) {
			emptyList = true;

		for (Volume itemVolume : volume) {
			if (itemVolume.getVolumeId() == volumeId)
				found = true;

		if (found && emptyList) {
			SessionMessages.add(request, "no-cases-found");
		} else if (found && !emptyList) {
			Volume vol = DBUtil.getVolumefromRequest(request);
			idVol = vol.getVolumeId();

			if (idVol == 1) {
				System.out.println("Volume id iniziale: " + volumeId);
				SessionErrors.add(request, "error-volume");
			} else if (SearchValidator.volumeNotNull(idVol) && !(idVol == 1))

				System.out.println("Volume id action : " + vol.getVolumeId());

				response.setRenderParameter("volId", volumeIdentifier);
				System.out.println("search volume clicked");

				PortletPreferences prefs = request.getPreferences();
				String volumeIdent = request.getParameter("volumeId");
				if (volumeIdent != null) {
					prefs.setValue("volumeIdPref", volumeIdent);;


				SessionMessages.add(request, "search-volume");

		} else
			SessionErrors.add(request, "error-volume");

		response.setRenderParameter("jspPage", viewDatabaseJSP);


[b]JSP page[/b]:



	List volumes = VolumeLocalServiceUtil.getAllVolumes();
	List cases = CaseArchiveLocalServiceUtil.getAllCases();
	Long volumeIdentifier = 1L;

	Collections.sort(volumes, new Comparator() {
		public int compare(Volume o1, Volume o2) {
			Volume p1 = (Volume) o1;
			Volume p2 = (Volume) o2;
			return p1.getVolumeName().compareToIgnoreCase(

	PortletURL portletURL = renderResponse.createRenderURL();

	portletURL.setParameter("jspPage", "/html/admin/viewDatabase.jsp");

	int selected = 0;
	String volSel = null;

	PortletPreferences prefs = renderRequest.getPreferences();
	String volumeId = (String) prefs.getValue("volumeIdPref", "1");


		 1) {
						volumeIdentifier = (long) Integer.parseInt(volumeId);


					List tempResults = DBUtil

					results = ListUtil.subList(tempResults,

					total = tempResults.size();

					pageContext.setAttribute("results", results);
					pageContext.setAttribute("total", total);

					System.out.println("Cur PRINT:" + searchContainer.getCur());

					href="" name='view Case' />

 <a href="<%=cancelURL%>">← Back to Menu</a>

In the example above, volumeId is the form action parameter (passed by the select option), while volumeIdPref is the portlet preferences parameter, which keeps the value while consulting the pages.
In the action method, that is invoked when submitting the form value, i’ve set a response parameter called volId which is used in the jsp to set the variable value when invoking the search-container result page “1”. The render parameter is null when visiting the other pages, but it can be retrieved by the portlet preferences value.

I hope this helps. Let me know if you have questions or suggestions.

Liferay Service Builder with external database

To make a Liferay Service Builder with external database there are some rules to follow. This post will help you to get straight to the point.
Keep in mind that:

  • You can’t deploy more than one portlet mapping column with the same entity name, otherwise you get a hot-Deployment error.
  • the names of the portlet name, namespace and database must be distinct (ex. portlet=”imageview“, namespace=”mammography“, database=”dicomviewer“).
  • when you add external jar, you must add them in the Tomcat/lib/ext
    so liferay can find them in the global classpath.

The steps to make the service builder with the external database mapping are:

  1. make the service.xml file in the /docroot/WEB-INF/
  2. launch the build-service ant command
  3. add the ext-spring.xml file in the /docroot/WEB-INF/src/META-INF/ folder
  4. deploy the portlet.

The example below might be helpful.

—service.xml ————

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE service-builder PUBLIC "-//Liferay//DTD Service Builder 6.0.0//EN" "">

<service-builder package-path="it.dicom">
<author>Laura Liparulo</author>

<entity name="Volume" local-service="true" remote-service="true" table="volume"
data-source="mammographyDataSource" session-factory="mammographySessionFactory" tx-manager="mammographyTransactionManager">
<!-- PK Fields -->
<column name="volumeId" type="long" primary="true" />
<!-- Other Fields -->
<column name="volumeName" type="String" />
<!-- Relationships -->
<column name="caseVolume" type="Collection" entity="CaseArchive"
mapping-key="volumeId" />
<order by="asc">
<order-column name="volumeName" />

<finder name="Volume_Name" return-type="Collection">
<finder-column name="volumeName" />

<entity name="CaseArchive" local-service="true" remote-service="true" table="case_archive"
data-source="mammographyDataSource" session-factory="mammographySessionFactory" tx-manager="mammographyTransactionManager">
<!-- PK Fields -->
<column name="caseId" type="long" primary="true" />
<!-- Other Fields -->
<column name="caseName" type="String" />
<column name="volumeId" type="long" />
<column name="notes" type="String" />
<!-- Relationships -->
<column name="image_Case" type="Collection" entity="Image"
mapping-key="caseId" />
<order by="asc">
<order-column name="caseName" />
<finder name="Case_Name" return-type="Collection">
<finder-column name="caseName" />



—ext-spring.xml ————

<?xml version="1.0"?>
<bean id="mammographyDataSourceTarget"
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/dicomviewer" />
<property name="username" value="root" />

<property name="password" value="tigertailz" />
<bean id="mammographyDataSource"
<property name="targetDataSource">
<ref bean="mammographyDataSourceTarget" />
<bean id="mammographyHibernateSessionFactory"
<property name="dataSource">
<ref bean="mammographyDataSource" />
<bean id="mammographySessionFactory">
<property name="sessionFactoryImplementor">
<ref bean="mammographyHibernateSessionFactory" />

<bean id="mammographyTransactionManager"
<property name="dataSource">
<ref bean="mammographyDataSource" />
<property name="sessionFactory">
<ref bean="mammographyHibernateSessionFactory" />

Now you can make it fast as a shark! 🙂