« Back to Templating Languages

Access Liferay Services in Velocity

(Redirected from Access to 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
32424 Views
Average (4 Votes)
Comments

Showing 9 Comments

Thomas Kellerer
4/14/09 3:49 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)

Dave Mosher
6/22/09 11:41 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

Hemen Punjani
12/27/10 6:44 AM

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

Dave Weitzel
7/25/11 11:30 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?

Tom Mahy
10/17/11 1:52 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

P.C. SUN
10/25/11 2:26 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.

P.C. SUN
10/25/11 7:22 PM

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

Nagendra Kumar Busam
12/1/11 5:22 AM

Try this

$layoutService.getLayouts$getterUtil.getLong($group_id), $layout.isPrivateLayout())

Nagendra Kumar Busam
12/1/11 5:23 AM

Sorry, typo
$layoutService.getLayouts($getterUtil.getLong($group_id), $layout.isPrivateLayout())