Deploying enterprise liferay dependency in local maven repository

Download the Liferay maven kit from Liferay customer portal and unzip it.

Configure the local maven repository path and id in the {unzippedliferaymavenkit}\build.properties file.

gpg.keyname=
gpg.passphrase=
lp.version.maven=6.2.10.5
lp.maven.repository.id=mavenrepoid
lp.maven.repository.url=http://localmavenrepositoryserver:port/nexus/content/repositories/snapshots

Add the local maven repository username and password in the {userhomedir}\.m2\settings.xml file

<servers>
 <server>
 <id>mavenrepoid</id>
 <username>username</username>
 <password>password</password>
 </server>
</servers>

Make sure the maven repository id in the build.properties file is same to server id in the settings.xml file.

Run ‘ant install’ command

After successful installation. you will be able to use Liferay libraries as maven dependency in your project.

pom.xml 

 <!-- <span class="hiddenSpellError" pre="" data-mce-bogus="1">Liferay</span> dependencies -->
 <dependency>
 <groupId>com.liferay.portal</groupId>
 <artifactId>portal-client</artifactId>
 <version>${com-liferay-portal-version}</version>
 <scope>provided</scope>
 </dependency>
 <dependency>
 <groupId>com.liferay.portal</groupId>
 <artifactId>portal-impl</artifactId>
 <version>${com-liferay-portal-version}</version>
 <scope>provided</scope>
 </dependency>
 <dependency>
 <groupId>com.liferay.portal</groupId>
 <artifactId>portal-kernel</artifactId>
 <version>6.2.10.5</version>
 <scope>provided</scope>
 </dependency>
 <dependency>
 <groupId>com.liferay.portal</groupId>
 <artifactId>portal-service</artifactId>
 <version>${com-liferay-portal-version}</version>
 <scope>provided</scope>
 </dependency>
 <dependency>
 <groupId>com.liferay.portal</groupId>
 <artifactId>portal-web</artifactId>
 <version>6.2.10.5</version>
 <scope>provided</scope>
 </dependency>
 <dependency>
 <groupId>com.liferay.portal</groupId>
 <artifactId>util-bridges</artifactId>
 <version>6.2.10.5</version>
 </dependency>
 <dependency>
 <groupId>com.liferay.portal</groupId>
 <artifactId>util-java</artifactId>
 <version>6.2.10.5</version>
 </dependency>
 <dependency>
 <groupId>com.liferay.portal</groupId>
 <artifactId>util-taglib</artifactId>
 <version>6.2.10.5</version>
 </dependency>

Definitely, your pom.xml should contain the repository path of your local repository.

 <repositories>
 <repository>
 <id>mavenrepoid</id>
 <name>Internal Snapshots</name>
 <url>http://localmavenrepositoryserver:port/nexus/content/repositories/snapshots</url>
 </repository>
 </repositories>

And if you are using the proxy configuration in your setting.xml file. configure local maven repository to by-pass the proxy.

<proxies>
 <proxy>
 <active>true</active>
 <protocol>http</protocol>
 <host>proxyhost</host>
 <port>proxyport</port>
 localhost|<strong>localmavenrepositoryserver</strong></nonProxyHosts>
 </proxy>
 </proxies>

Adding dependency module for portlet deployed in Liferay Jboss

Liferay adds jboss-deployment descriptor, when we deploy a portlet on Liferay-Jboss container, which is used for controlling the class loading. And by default it excludes all the javaee dependencies from the class path.

<?xml version="1.0" encoding="UTF-8"?>
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.1">
	<deployment>
		<exclusions>
			<module name="javaee.api" />
			<module name="org.apache.log4j" />
		</exclusions>
		<dependencies>
			<module meta-inf="export" name="com.liferay.portal">
				<imports>
					<include path="META-INF" />
				</imports>
			</module>			
			<module name="javax.mail.api" />
			<module name="org.jboss.modules" />
		</dependencies>
	</deployment>
</jboss-deployment-structure>

In case, a specific javaee module is required by your portlet. we can add that specific module in jboss-deployment-structure file, to make that module available to your portlet.

e.g. in my case, portlet was using the JAX-WS APIs. And I have added the following configuration, to make this module available to my portlet

 <module name="javax.xml.ws.api" />

Alloy UI : Custom validation and customising default validations

In this post, I am going to mention about two things

  1. How to customize alloy ui default validation.
  2. How to add custom validation in alloy ui.

Recently, I have faced a problem while working with Liferay Alloy UI validation, in firefox browser. Issue was, in case of blank field, placeholder value was acting as default value of field and validation was trying to validate the place holder value. I have customized the Liferay Alloy UI validation to fix this issue. Below is the code snippet for the same.

<aui:script></pre>
<pre>         AUI().use('aui-base','aui-form-validator','liferay-form',function(A){
			var DEFAULTS_FORM_VALIDATOR = AUI.defaults.FormValidator;

			var defaultEmail = DEFAULTS_FORM_VALIDATOR.RULES.email;
			var defaultDigits = DEFAULTS_FORM_VALIDATOR.RULES.digits;
			var defaultRequired = DEFAULTS_FORM_VALIDATOR.RULES.required;
			var defaultMaxLength = DEFAULTS_FORM_VALIDATOR.RULES.maxLength;

			var email = function(val, node, ruleValue) {
				if(node.attr('value') == node.attr('placeholder') ){
					return true;
				}
				return defaultEmail(val, node, ruleValue);
			};	

			var digits = function(val, node, ruleValue) {
				if(node.attr('value') == node.attr('placeholder') ){
					return true;
				}
				return defaultDigits(val, node, ruleValue);
			};	

			var required = function(val, node, ruleValue) {
				//alert('Val :['+val +'] Type :['+node.attr('type')+']');
				//alert(node.attr('type') == 'hidden' && node.attr('value') == 'false');

				if(node.attr('type') == 'hidden' && node.attr('value') == 'false'){
				    return false;
				}
				if(node.attr('value') == node.attr('placeholder') ){
					return false;
				}
				return defaultRequired(val, node, ruleValue);
			};		

			var maxLength = function(val, node, ruleValue) {
				if(node.attr('value') == node.attr('placeholder') ){
					return false;
				}
				return defaultMaxLength(val, node, ruleValue);
			};	

			var phone = function(val, node, ruleValue) {
				if(node.attr('value') == node.attr('placeholder') ){
					return false;
				}	

				var phoneRegExp = /^((\+)?[1-9]{1,2})?([-\s\.])?((\(\d{1,4}\))|\d{1,4})(([-\s\.])?[0-9]{1,12}){1,2}$/;
				// valid phone number match
				// 2155552527|(215) 555 2527|215.555.2527|+1 215-555-2527|+1.215.555.2527

			    var numbers = val.split('').length;
			    if (5 <= numbers && numbers <= 20 && phoneRegExp.test(val)) {
					return true;
			    }
			    return false;
			}

			A.mix(
				DEFAULTS_FORM_VALIDATOR.RULES,
				{
					email	 : email,
					digits	 : digits,
					maxLength: maxLength,
					required : required,
					phone    : phone
				},
				true
			);		

			A.mix(
				DEFAULTS_FORM_VALIDATOR.STRINGS,
				{
					phone    : 'Please enter valid phone number'
				},
				true
			);
   });

The above code snippet also has the custom validation for the phone . And we can use custom phone validation by using the following validation tag.

<aui:validator name="phone">

Load Liferay portlet by Ajax

To load a page, Liferay load all the portlet on the page. And if there are many portlets on the same page and some portlets require more time to load the data, the page will only be shown when all portlets have delivered the data.

If we want to load the page without waiting for the portlets which are taking more time in loading and let those portlets load in the background by ajax after loading of the page. We can do this in Liferay by adding the following configuration in the liferay-portlet.xml.

<render-weight>0</render-weight>
<ajaxable>true</ajaxable>

If we add these configuration to a porltet. Liferay will not load that portlet content while loading the page, but it will render some javascript code on browser for that portlet. that javascript code will fetch the portlet content by ajax call.

 

List of Portal properties which can be modified through Liferay hook plugin

Not all portal properties can be overridden via a hook. Below is the list of properties which can be modified though the liferay hook plugin.

admin.default.group.names
admin.default.role.names
admin.default.user.group.names
asset.publisher.asset.entry.query.processors
asset.publisher.display.styles
asset.publisher.query.form.configuration
auth.forward.by.last.path
auth.public.paths
auto.deploy.listeners
application.startup.events
auth.failure
auth.max.failures
auth.token.ignore.actions
auth.token.ignore.portlets
auth.token.impl
auth.pipeline.post
auth.pipeline.pre
auto.login.hooks
captcha.check.portal.create_account
captcha.engine.impl
com.liferay.portal.servlet.filters.*Filter
company.default.locale
company.default.time.zone
company.settings.form.authentication
company.settings.form.configuration
company.settings.form.identification
company.settings.form.miscellaneous
control.panel.entry.class.default
convert.processes
default.landing.page.path
default.regular.color.scheme.id
default.regular.theme.id
default.wap.color.scheme.id
default.wap.theme.id
dl.file.entry.drafts.enabled
dl.file.entry.processors
dl.repository.impl
dl.store.antivirus.impl
dl.store.impl
dockbar.add.portlets
field.enable.com.liferay.portal.model.Contact.birthday
field.enable.com.liferay.portal.model.Contact.male
field.enable.com.liferay.portal.model.Organization.status
hot.deploy.listeners
javascript.fast.load
journal.article.form.add
journal.article.form.translate
journal.article.form.update
layout.form.add
layout.form.update
layout.set.form.update
layout.static.portlets.all
layout.template.cache.enabled
layout.types
layout.user.private.layouts.auto.create
layout.user.private.layouts.enabled
layout.user.private.layouts.power.user.required
layout.user.public.layouts.auto.create
layout.user.public.layouts.enabled
layout.user.public.layouts.power.user.required
ldap.attrs.transformer.impl
locales
locales.beta
locales.enabled
lock.listeners
login.create.account.allow.custom.password
login.events.post
login.events.pre
login.form.navigation.post
login.form.navigation.pre
logout.events.post
logout.events.pre
mail.hook.impl
my.sites.show.private.sites.with.no.layouts
my.sites.show.public.sites.with.no.layouts
my.sites.show.user.private.sites.with.no.layouts
my.sites.show.user.public.sites.with.no.layouts
organizations.form.add.identification
organizations.form.add.main
organizations.form.add.miscellaneous
passwords.passwordpolicytoolkit.generator
passwords.passwordpolicytoolkit.static
passwords.toolkit
phone.number.format.impl
phone.number.format.international.regexp
phone.number.format.usa.regexp
portlet.add.default.resource.check.enabled
portlet.add.default.resource.check.whitelist
portlet.add.default.resource.check.whitelist.actions
rss.feeds.enabled
sanitizer.impl
servlet.session.create.events
servlet.session.destroy.events
servlet.service.events.post
servlet.service.events.pre
session.max.allowed
session.phishing.protected.attributes
session.store.password
sites.form.add.advanced
sites.form.add.main
sites.form.add.seo
sites.form.update.advanced
sites.form.update.main
sites.form.update.seo
social.activity.sets.bundling.enabled
social.activity.sets.enabled
social.activity.sets.selector
social.bookmark.*
terms.of.use.required
theme.css.fast.load
theme.images.fast.load
theme.jsp.override.enabled
theme.loader.new.theme.id.on.import
theme.portlet.decorate.default
theme.portlet.sharing.default
theme.shortcut.icon
time.zones
upgrade.processes
user.notification.event.confirmation.enabled
users.email.address.generator
users.email.address.required
users.email.address.validator
users.form.add.identification
users.form.add.main
users.form.add.miscellaneous
users.form.my.account.identification
users.form.my.account.main
users.form.my.account.miscellaneous
users.form.update.identification
users.form.update.main
users.form.update.miscellaneous
users.full.name.generator
users.full.name.validator
users.image.max.height
users.image.max.width
users.screen.name.always.autogenerate
users.screen.name.generator
users.screen.name.validator
value.object.listener.*

Liferay : Same web content showing with different display template.

For Advance Web content management, Liferay provides the features of structures and templates. Structures are used for creating the data entry form for the content creators and Templates are responsible for look and feel of a web content on web page.

Suppose, if we want, a single piece of web content( article id is ‘weContentArticleId’)  to display with two different display template( template id is ‘displayTemplateId1′ and ‘displayTemplateId1′) for different look and feel.

We can do it, by using the liferay OOTB Web Content Display Portlet. In the configuration mode, it provides the option for overriding the default display tempalte associated with the web content.

We can also do the same thing through the tag library as well.

e.g.

<liferay-ui:journal-article articleId=”webContentArtilceId” groupId=”<%= themeDisplay.getScopeGroupId() %>” templateId=”displayTemplateId1″ />

<liferay-ui:journal-article articleId=”webContentArtilceId” groupId=”<%= themeDisplay.getScopeGroupId() %>” templateId=”displayTemplateId2″ />