
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.