« Back to 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 Attachments
88416 Views
Average (4 Votes)
The average rating is 3.0 stars out of 5.
Comments
Threaded Replies Author Date
Doesn't work for me in 5.2.2 My... Thomas Kellerer April 14, 2009 3:49 AM
I haven't gotten this to work either, but then... Dave Mosher June 22, 2009 11:41 AM
Doesnt work for me in 5.2.2 i was trying to use... Hemen Punjani December 27, 2010 6:44 AM
I am having difficulty using this information... Dave Weitzel July 25, 2011 11:30 AM
try this : #set($layoutLocalService =... Tom Mahy October 17, 2011 1:52 AM
Hi, I tried following things, really strange... P.C. SUN October 25, 2011 2:26 AM
Hi All, I checked the codes and make some... P.C. SUN October 25, 2011 7:22 PM
Try this ... Nagendra Kumar Busam December 1, 2011 5:22 AM
Sorry, typo... Nagendra Kumar Busam December 1, 2011 5:23 AM
Great post. I have a question: Is it... David García González March 1, 2012 4:38 AM
Hi Gurus, I try to use ExceptionSafeService in... Dilip H Chauhan September 12, 2012 6:39 AM
in case you get ... A A June 25, 2013 6:55 AM

Doesn't work for me in 5.2.2

My portal-ext.properties contains the following line:

journal.template.velocity.restricted.variables=

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)
Posted on 4/14/09 3:49 AM.
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.
journal.template.velocity.restricted.variables=true
Posted on 6/22/09 11:41 AM in reply to 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"))

$layout.getFriendlyURL()

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

Please suggest
Posted on 12/27/10 6:44 AM.
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?
Posted on 7/25/11 11:30 AM.
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
Posted on 10/17/11 1:52 AM.
Hi,

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


1. Codes:
<script>
#set($layoutService = $serviceLocator.findService("com.liferay.portal.service.LayoutLocalService"))
#se­t($mylayouts = $layoutService.getLayouts(-1, -1))
alert('$mylayouts');
</script>

Results: No Output…(INCORRECT)

2. Codes:
<script>
#set($layoutService = $serviceLocator.findService("com.liferay.portal.service.LayoutLocalService"))
#se­t($mylayouts = $layoutService.getLayoutsCount ())
alert('$mylayouts');
</script>

Results: Alert 112 (CORRECT)

3. Codes:
<script>
#set($layoutService = $serviceLocator.findService("com.liferay.portal.service.UserLocalService"))
#set(­$mylayouts = $layoutService.getUsers (-1,-1))
alert('$mylayouts');
</script>

Results: Alert User List Info (CORRECT)

Anyone could suggest what happened there please?

Thanks in advance.
Posted on 10/25/11 2:26 AM in reply to Tom Mahy.
Hi All,

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

-------

<script>
#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])

alert("$mylayouts.get($cntGL).getName("en_US")");

#end
#end
<­/script>

-------

Notice:

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
Posted on 10/25/11 7:22 PM in reply to P.C. SUN.
Try this

$layoutService.getLayouts$getterUtil.getLong($group_id), $layout.isPrivateLayout())
Posted on 12/1/11 5:22 AM in reply to P.C. SUN.
Sorry, typo
$layoutService.getLayouts($getterUtil.getLong($group_id), $layout.isPrivateLayout())
Posted on 12/1/11 5:23 AM in reply to 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:

com.liferay.portal.util.FriendlyURLNormalizer

Is this possible?
Posted on 3/1/12 4:38 AM.
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
Posted on 9/12/12 6:39 AM.
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.
Posted on 6/25/13 6:55 AM.