« Torna a Templating Languages

Access Liferay Services in Velocity

Introduction #

Velocity enables you to access Liferay services from within your themes and CMS templates. It is provided through a utility known as Service Locator.

The findService() Method #

For example, suppose you need layoutLocalService:

#set($layoutLocalService = $serviceLocator.findService("com.liferay.portal.service.LayoutLocalService"))

#set($xyz = $layoutLocalService.getFriendlyURLLayout($layout.getOwnerId(), "/home")) 

The services obtained from the findService method are the raw services and sometimes they can be difficult to work with because Velocity does not provide an exception handling mechanism.

Exception Handling #

To handle this issue, more recent versions of Liferay (5.1.0+) provide a second method, findExceptionSafeService which wraps the underlying service with a proxy which catches any exceptions and simply returns null.

For example, suppose you want to see if some userId refers to an actual user:

#set($userLocalService = $serviceLocator.findExceptionSafeService("com.liferay.portal.service.UserLocalService"))

The following method would typically crash the VM being processed, because it throws a NoSuchUserException if the user cannot be located.

#set($user = $userLocalService.getUserById($getterUtil.getLong("12345"))

Service Locator Not Working? #

ServiceLocator is a feature which unlocks a lot of power. This power can inadvertently fall into the wrong hands if for example Journal Template creation is granted to less trusted users. Therefore to prevent abuse, or simply to protect less aware portal admins, the feature is disabled by default for all Journal VM contexts.

To enable it, edit the value of journal.template.velocity.restricted.variables in portal.properties. See Journal Portlet section of the Portal Properties area.

Example: Building a Navigation #

 #set($layoutService = $serviceLocator.findService("com.liferay.portal.service.LayoutLocalService"))
 #set($ancLayout = $layoutService.getLayout($layout.getAncestorLayoutId(),$layout.getOwnerId()))
 #set($ancLayoutName = $ancLayout.getName($locale))
 #set($ancLayoutChildren = $ancLayout.getChildren())
 #set($layoutsChildren = $layout.getChildren())
 #set($ancLayoutLink = $ancLayout.getFriendlyURL())

So what does this do?

We create a variable called layoutService that contains the com.liferay.portal.service.LayoutLocalService class.

From there we can call it, just like we would in a jsp or java file.

What this code does is make it so you can get the current layout that you are on. This makes it so that we could get the current group information as well, by adding this below the code:

 #** Get the group name *#
 #set($currentGroup = $layout.getGroup())
 #set($currentGroupName = $currentGroup.getName())
 #set($currentGroupURL = $currentGroup.getFriendlyURL())
 #set($templayouts = $layout.getChildren())

You can see that we're getting the group info from the layout, and then getting its children.

Which classes are available? #

Themes #

Since the answer to this is constantly changing, it is best to look in portal-impl/src/com/liferay/portal/velocity/VelocityVariables.java

This is where all the objects are injected into the velocity templates. Anything set here is available as you see it. For example, you should see Layout layout = themeDisplay.getLayout();

And following that velocityContext.put("layout", layout);

Which means in a velocity file, you can access $layout.getName()

Which will give you the layout name, just like in a regular java file.

Web Content #

The velocity variables available in Web Content are set in JournalVmUtil. Please see that file for the current list of available variables in a Web Content piece. Up-to-date list of velocity variables (and all public methods available for each variable) can also be found using Velocity Variable Explorer.

See Also #

0 Allegati
155636 Visualizzazioni
Media (4 Voti)
La media del punteggio è 3.0 stelle su 5.
Commenti Autore Data
Doesn't work for me in 5.2.2 My... Thomas Kellerer 14 aprile 2009 3.49
I haven't gotten this to work either, but then... Dave Mosher 22 giugno 2009 11.41
Doesnt work for me in 5.2.2 i was trying to use... Hemen Punjani 27 dicembre 2010 6.44
I am having difficulty using this information... Dave Weitzel 25 luglio 2011 11.30
try this : #set($layoutLocalService =... Tom Mahy 17 ottobre 2011 1.52
Hi, I tried following things, really strange... P.C. SUN 25 ottobre 2011 2.26
Hi All, I checked the codes and make some... P.C. SUN 25 ottobre 2011 19.22
Try this ... Nagendra Kumar Busam 1 dicembre 2011 5.22
Sorry, typo... Nagendra Kumar Busam 1 dicembre 2011 5.23
Great post. I have a question: Is it... David García González 1 marzo 2012 4.38
Hi Gurus, I try to use ExceptionSafeService in... Dilip H Chauhan 12 settembre 2012 6.39
in case you get ... A A 25 giugno 2013 6.55

Doesn't work for me in 5.2.2

My portal-ext.properties contains the following line:


But still I can't use the service inside a Velocity template.

But I assume this is more caused by the fact that the $layout variable is not working in my template. If I simply put $layout.getOwnerId() into my VM template, it does not retrieve the ID, but displays that text literally (which usually means that the Variable is not defined for Liferay)
Inviato il 14/04/09 3.49.
I haven't gotten this to work either, but then again I don't have server-side access. Yet.

Idea: Have you tried toggling the value to "true" or "false"? E.g.
Inviato il 22/06/09 11.41 in risposta a Thomas Kellerer.
Doesnt work for me in 5.2.2
i was trying to use findExceptionSafeService method as mentioned below...

#set($LayoutLocalServiceUtil = $serviceLocator.findExceptionSafeService("com.liferay.portal.service.LayoutLocal­ServiceUtil"))
#set($layout = $LayoutLocalServiceUtil.getFriendlyURLLayout($themeDisplay.getScopeGroupId(),fal­se,"/the/wrong/url"))


but its not giving me the $layout as null.
It gives me the current layout's url.

Please suggest
Inviato il 27/12/10 6.44.
I am having difficulty using this information within CMS templates.
for example the layout object is not available by default, so all the examples for the layoutServiceLocator are not useful as you pass $layout properties to the call to the service.
All I am trying to do is ascertain if the current page is the "home" page for a group's layout from WITHIN the CMS template not a theme. I believe this is layout.layoutId()=1 but I need to get the layout object.

I have made serviceLocator available but cannot seem to get it or some other example code to run (eg $request.theme-display.example type refernces)

has anyone else got code to identify which page is being displayed within a layoutSet?
Inviato il 25/07/11 11.30.
try this :

#set($layoutLocalService = $serviceLocator.findService("com.liferay.portal.service.LayoutLocalService"))
#se­t($xyz = $layoutLocalService.getFriendlyURLLayout($layout.getOwnerId(), "/home"))

$layoutLocalService gives me the impl class.
but when i add $xyz to the page it shows $xyz and not the value.

liferay 6.0.6
Inviato il 17/10/11 1.52.

I tried following things, really strange for me. Some methodS of layout I could call, some others not. Sample Codes:

1. Codes:
#set($layoutService = $serviceLocator.findService("com.liferay.portal.service.LayoutLocalService"))
#se­t($mylayouts = $layoutService.getLayouts(-1, -1))

Results: No Output…(INCORRECT)

2. Codes:
#set($layoutService = $serviceLocator.findService("com.liferay.portal.service.LayoutLocalService"))
#se­t($mylayouts = $layoutService.getLayoutsCount ())

Results: Alert 112 (CORRECT)

3. Codes:
#set($layoutService = $serviceLocator.findService("com.liferay.portal.service.UserLocalService"))
#set(­$mylayouts = $layoutService.getUsers (-1,-1))

Results: Alert User List Info (CORRECT)

Anyone could suggest what happened there please?

Thanks in advance.
Inviato il 25/10/11 2.26 in risposta a Tom Mahy.
Hi All,

I checked the codes and make some test, finally it works. Here are my codes:


#set($layoutService = $serviceLocator.findService("com.liferay.portal.service.LayoutLocalService"))
#se­t($mylayouts = $layoutService.getLayouts(10157, false, 0))
#set($count = $mylayouts.size() - 1)

#if($count != -1)
#foreach($cntGL in [0..$count])





In alert stmt, do not use ('), use (") instead. And for stmt $layoutService.getLayouts(10157, false, 0) - 10157 is the group ID, 0 is the ancester layout ID. And in foreach loop, I did not use #foreach($a in $b.getChildren()), since it is not working.

And one more thing which is wired for me is: I still can't use $layoutService.getLayouts(-1,-1), which could get all layouts. Anyone gets one sample, please let me know.

Thanks. emoticon

Best Regards
Inviato il 25/10/11 19.22 in risposta a P.C. SUN.
Try this

$layoutService.getLayouts$getterUtil.getLong($group_id), $layout.isPrivateLayout())
Inviato il 01/12/11 5.22 in risposta a P.C. SUN.
Sorry, typo
$layoutService.getLayouts($getterUtil.getLong($group_id), $layout.isPrivateLayout())
Inviato il 01/12/11 5.23 in risposta a Nagendra Kumar Busam.
Great post.

I have a question:

Is it possible to use a static method from a velocity template for a structure?
I wanted to use the class:


Is this possible?
Inviato il 01/03/12 4.38.
Hi Gurus,

I try to use ExceptionSafeService in Liferay 6.1.20 ga2 but its not working in this liferay instance .
Let me know If any One have use this in this version.

Anyone could suggest or give me any idea regarding this
Inviato il 12/09/12 6.39.
in case you get
org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named '...' is defined OR BeanLocator has not been set for servlet context
try using:
#set($layoutLocalService = $serviceLocator.findService("my-war-name", "com.liferay.portal.service.LayoutLocalService"))

where "my-war-name" is a name of war that you deploy (or, same, name of your app in tomcat/webapps) which contatins service bean you want to use. In case of custom service - reference implenetation bean, not util class with static methods.
Inviato il 25/06/13 6.55.