Leveraging OSGi to Create Extensible Applications for Liferay 6.2

Company Blogs October 20, 2014 By Eduardo P. Garcia Staff

It was great to participate in the Liferay North American Symposium this year. With hundreds of Liferay users (customers, partners, community members...) and dozens of presentations, it was not only a huge success but also a great opportunity to share user experiences and get your feedback. North American Symposium is over, but Liferay World Tour 2014 is not! There are still many important events in our calendar so you still have the chance to learn about Liferay latest features firsthand. 
 
Julio Camarero and I will be talking about Extensible Liferay Applications in the Spanish Symposium next week and in the Developer Conference in early November. This is probably one of the most relevant features in Liferay 6.2 because it's meant to completely change how Liferay applications are developed. Let's find out how with a simple example:
 

A Shipping Cost Calculator

Suppose you have an online shop and you need an application to calculate the final cost of purchasing an item, including its shipping to destination and considering not only the distance but also the currency, the local taxes and any other particularities. Thus, the final cost would be:
 
Final cost = [no. of items x item price] + [shipping cost to selected destination]
 
As a developer you could implement a very complex application that contains all possible shipping destinations. Every time you wanted to add or modify a shipping destination, you’d have to release a new version of your application. And likely your application would be more and more complex with every new release.
Alternatively, you could implement just the core functions of your calculator and define the shipping destinations as extensions to your application. This way, if you needed to add or modify a shipping destination those changes would not affect to the core functions, but only to an specific extension. With this approach, the release frequency of your core application as well as its complexity would decrease. Instead, new features would be added through small extensions with their own release frequency.

Modular and Extensible Applications: the OSGi Way

Probably at this point you’ve already realized the benefits of the second approach: 
  • Simpler maintenance of the core application by reducing its complexity
  • Better performance (only required extensions would be installed)
  • Support for third party extensions
  • New market opportunities (e.g. purchasing shipping extensions)
This type of modular and extensible applications are defined by the OSGi  (Open Service Gateway initiative) specification. Thanks to Liferay support for OSGi since version 6.2, you can now apply this pattern to your plugins. 
 
We recommend you to go through the documentation about OSGi apps in Liferay. For now we’ll show some quick guidelines to apply this pattern to the Shipping Cost Calculator project. You can also have a look to the complete source code of this project.
 

Required Services for an Extensible Shipping Cost Calculator

OSGi services consist of:
  • An interface, defining the service “contract”
  • One or more implementations of the interface
To make our shipping cost calculator extensible, we need two types of OSGi services:
 

Shipping Extensions:

The ShippingExtension interface contains the methods that any shipping extension must implement. Implementations of this interface (e.g. ShippingExtensionUSA) are annotated with @Component, which allows OSGi to dynamically detect a new shipping extension when it’s deployed.
@Component(immediate = true, service = ShippingExtension.class)
public class ShippingExtensionUSA implements ShippingExtension {
 

ShippingExtension Registry

In order to have an up-to-date list with all the available shipping options, we need to track when these extensions (annotated with @Component) are deployed or undeployed. Through the @Referecene annotation the registerShippingExtension method of ShippingExtensionRegistryImpl is bound to the ShippingExtensionService, so it will be invoked every time an implementation of ShippingExtension is deployed. The unregisterShippingExtension method is called when an implementation is undeployed.
@Reference(
	unbind = "unregisterShippingExtension",
	cardinality = ReferenceCardinality.MULTIPLE,
	policy = ReferencePolicy.DYNAMIC)	
public void registerShippingExtension(ShippingExtension shippingExtension) {
	_shippingExtensions.put(
		shippingExtension.getShippingExtensionKey(), shippingExtension);
}

 

Accessing OSGi services from a non OSGi context: the ServiceTrackerUtil

We’re almost done. All we need to do is to list the shipping extensions registered by the ShippingExtensionRegistry in our GUI and process the resulting form according to the selected option. Since our GUI is still a Liferay portlet, which is not handled by the OSGi service container (yet), we cannot use the @Reference annotation to obtain the ShippingExtension service. Liferay provides a util class for this purpose: the ServiceTrackerUtil.
_shippingExtensionRegistry = ServiceTrackerUtil.getService(
	ShippingExtensionRegistry.class, bundle.getBundleContext());
 
You can now test the app. First deploy all modules to your Liferay server, except for the shipping extensions. Then browse any site page and add the Shipping portlet. Notice that the calculator is functional, but it displays no shipping options. Now deploy the shipping extensions one by one, refreshing the page every time. You’ll now see a list with the available shipping extensions. Selecting a shipping extension will modify the form and the final result.
 
 

Going even deeper in modularization

If you have worked with the sample code, you may have noticed that the core application is not contained in a single project, but in three: 
  • shipping-api: Contains only the interfaces of the OSGi services that make up the app
  • shipping-impl: Contains the implementation of the core OSGi services of the app
  • shipping-web: Contains the user interface of the app
With this approach, the core of application can be easily modified by changing the implementation or the web interface, without changing the public API. 
 
Audience Targeting is the first official Liferay application that is built following this OSGi way, but this is actually how all Liferay apps will be in the next version of Liferay Portal so WELCOME TO THE FUTURE!!

Application Display Templates: Challenge Accepted!

Company Blogs September 29, 2014 By Eduardo P. Garcia Staff

It’s less than a week left until Liferay North America Symposium (NAS), the first of a series of events where we’ll have the chance to first-hand explain to our users what we’ve been working on this year. In particular, workshops will give us the opportunity to go deeper in some of our most popular features, as we will have the time to review and solve some real use cases.

In previous events we had shown you how Application Display Templates can change not only the look and feel but also the function of some applications. But in the NAS workshop we will demonstrate how they be used to change a whole site.  For this challenge we’ve prepared a full demo music site.

Our goal during the workshop will be not only to improve the design, but also to add new features by creating and applying new Application Display Templates to Liferay applications. For instance, among other many exercises we’ll see how to display our content as a chart or even as a map with the Asset Publisher.

And the challenge will go even further. Since our music site uses some custom applications, we will learn how to make them support Application Display Templates, so that we can also extend their display modes with new templates. See before and after:

Finally, for those of you who are so proud of your Application Display Templates that can’t wait for the world to see them, we will show you how make them distributable through Liferay Marketplace.

Sounds good,  doesn’t it? If you haven’t yet, visit the NAS site and register now! And for those of you who cannot make it for the NAS, you’ll have yet another chance in the Liferay Spanish Symposium and the Liferay Developer Conference.

Thanks a lot to Marcos Castro, for his wonderful design for the Music Site :-).

See you in Boston!

Upcoming customization options with Application Display Templates

Company Blogs June 12, 2014 By Eduardo P. Garcia Staff

Application Display Templates have become one of the most popular features in Liferay Portal 6.2. Last year we reviewed how to use this powerful tool to customize some Liferay portlets. Furthermore we explained how developers can apply the same feature to their custom portlets in just a few steps.

The Liferay Community provides a great feedback about how you use Application Display Templates and also about the Liferay portlets where you miss this feature. And of course, we have attended your requests cool

Customizing the Language Portlet

The Language Portlet as you know it

Definitely one of your favorites to join the Application Display Templates family. You can now customize every single detail of this portlet. For example, you can turn it into an icon-menu list like this:

The Language Portlet displayed as an icon-menu thanks to Application Display Templates

 

Your breadcrumb will never look the same

The Breadcrumb Portlet as you know it

The Breadcrumb portlet already included some customization options. But you wanted more, and we’ve given you all yes. With Application Display Templates, there’s no limit to your creativity. See how different your breadcrumb can look with just a very simple template:

The Breadcrumb Portlet with a brand new style thanks to Application Display Templates

Thanks Jose Manuel!

Displaying content on a map? Yes, you can!

We are not only extending the support for Application Display Templates to more portlets, but we are also extending the possibilities that this tool provides to display content in a completely new way.

Just a very cool example of this is the work that our colleagues Sergio, Bruno and Adolfo have done with the content geolocation feature. In a nutshell, you can define your content associated coordinates through a new geolocation input field. Among the number of possibilities that this information brings, you can now display your content on a map with the Asset Publisher portlet and a very simple Application Display Template. For example, you can change from this:

A typical list of content with the Asset Publisher

to this:

Content on a Map with Application Display Templates and Google Maps

Content on a Map with Application Display Templates and OpenStreetMap

And these are just the first of a number of new features that Application Display Templates will include in the next version of Liferay Portal. Remember that you can request new features through our website. Thanks for helping us make Liferay Portal a little better everyday heart!

Making Liferay Portal 6.2 RTL friendly - The Right to Left plugin

Company Blogs May 29, 2014 By Eduardo P. Garcia Staff

Middle Eastern languages, such as Hebrew and Arabic, are written predominantly right-to-left (RTL). However, many sites written RTL also have left-to-right (LTR) content mixed in, making them bidirectional in nature. Conveniently, browsers use language and direction information of HTML tags to automatically adapt and align page content. However, sites may consist of elements that are absolutely positioned on the page by a style sheet; these elements aren't automatically aligned by the browser. Rather, you must adapt your style sheets to handle such elements. Since style sheets are usually designed for LTR languages, the typical challenge is creating alternative versions of the CSS for RTL languages. This can be an arduous task.
 
A few weeks ago our colleague Iliyan described on his blog how automatic adjustment to RTL will be supported out of the box in future Liferay Portal versions. In this blog we introduce the “Right to Left” plugin, a new Liferay application that automatically adapts Liferay Portal 6.2 styles for RTL languages.
 

Using the Right to Left plugin

To test how the Right to Left plugin works, lets create a simple site with one page and one single content translated to several languages, including LTR and RTL ones.

Before installing the Right to Left plugin, try to set your user language to Arabic or Hebrew. You’ll notice that some elements (such as paragraphs) are mirrored to match the RTL orientation. But some others (dockbar, images…) aren’t.

Now install the Right to Left plugin and reload the page. This time, every element on the page is mirrored for a full RTL experience.

Support for custom plugins

The simple test described above works fine with Liferay Portal default theme and portlets. But if you are using any custom plugins, such a theme, you will notice that its styles are not fully mirrored.

In order to provide full RTL support in custom plugins, developers have to go through a few steps described in the technical documentation of the Right to Left plugin. Then, once the plugin is redeployed its elements will be displayed mirrored for RTL languages (for LTR languages, they will be displayed as usual).

Fine style tuning for RTL languages

Through the steps described in the previous section, the styles in a custom plugin are automatically adapted so that the page elements are mirrored for RTL languages. This automatism covers most of the common scenarios. But developers can override it, so that they define how the page elements should behave for RTL languages.

For example, observe the header of our sample theme. It contains a line with hands pointing to the appropriate reading direction. But even after a developer has adapted the theme for RTL languages, the hands still point to the initial direction. Thanks to the overriding mechanism provided by the Right to Left plugin, our developer is able to set an alternative image for RTL languages only.

The same mechanism could be applied to force an element to be right or left aligned for both LTR and RTL languages, for example.

The Right to Left plugin is coming soon to our Marketplace. Enjoy it!

Did you know...?

The topic "The City  of Three Cultures" that was used for the screenshots in this blog refers to the time when Jewishs, Muslims and Christians coexisted peacefully in the city of Toledo, the ancient capital of Spain. Back then, king Alfonso X "The Wise" employed Jewish, Christian and Muslim scholars at his court, primarily for the purpose of translating books from Arabic and Hebrew into Latin and Castilian. This group of scholars formed his royal scriptorium, known as the "Escuela de Traductores de Toledo" (Toledo School of Translators). 

New Ways of Customization with Application Display Templates (Part II)

General Blogs October 9, 2013 By Eduardo P. Garcia Staff

 

The first Liferay DevCon has just started in Berlin and we just can't wait to present the world all new features in version 6.2. So I'm writing the second part of my blog about New Ways of Customization with Application Display Templates for those of you (eager like me) who just can't wait to use ADT in your portlets.
 
As you know Liferay is a Developer Friendly platform. We love developing and we love developers using and extending our product. So everytime we add a new framework we make sure it's not only accessible in the portlal, but also in the plugins. Security, Workflow, Asset... are only some examples of powerful features that can be exploded by your plugins. And in 6.2. we've added quite a few more! Let's focus on the ADT framework and see what you need to support this feature in your portlets.
 

Add ADT to your portlets in just 4 steps

In the first part of the blog we explained how ADT was implemented by reusing other existing services and features. We just added a management application to the Site Administration and a mechanism to allow any portlets to have and render their own templates. 
 
This second component is the key to have ADT in your portlets, and we'll describe how to use it in 4 simple steps:
 

1. Custom PortletDisplayTemplateHandler

To join the exclusive ADT club your portlet has to sign a contract committing itself to fulfill all the ADT features. In other words, you have to create a your own PortletDisplayTemplateHandler implementation by extending the BasePortletDisplayTemplateHandler methods. You can check the TemplateHandler interface javadoc to learn what every method is for. Basically:

public class MyAppPortletDisplayTemplateHandler extends BasePortletDisplayTemplateHandler { 
 
public String getClassName() {//Defines the type of entry your portlet is rendering}
   public String getName(Locale locale) {//Declares the name of your ADT type (typically, the name of the portlet)}  
public String getResourceName() {//Here you specify which resource is using the ADT (e.g. a portlet) for permission checking}  

public String getTemplatesHelpPath(String language) {//Adds a custom hint to the top of the ADT in the template editor}
public String[] getRestrictedVariables(String language) {//Provides a list with the restricted variables}   
public Map<String, TemplateVariableGroup> getTemplateVariableGroups(long classPK, String language, Locale locale) throws Exception {//Defines the variables exposed in the template editor}   
 

}

 
Once you've created your handler, you have to declare it in the right section of your liferay-portlet.xml.
<liferay-portlet-app>
 <portlet>
 <portlet-name>MyApp</portlet-name>
 … 
<template-handler>
 org.my.app.template.MyAppPortletDisplayTemplateHandler
 </template-handler>
 … 
</portlet>
 … 
</liferay-portlet-app>
 

2. Permissions

The action of adding ADTs is new to your portlet, so you want to be sure you can grant specific permissions for it. Just add this line to your resource actions file:
<resource-action-mapping>
 <portlet-resource>
 <portlet-name>MyApp</portlet-name>
 <permissions>
 <supports>
 <action-key>ADD_PORTLET_DISPLAY_TEMPLATE</action-key>
 … 
<supports>
 …
 <permissions>
 … 
<portlet-resource>
 … 
<resource-action-mapping>
 

3. Display settings configuration

Let's move to the frontend side of your portlet. Now your portlet officially supports ADT, you'll want to expose this option to your users. Just include the liferay-ui:ddm-template-selector taglib in your portlet configuration view providing the required information, like this:
 
<aui:form action="<%= configurationURL %>" method="post" name="fm">
 ...
 <aui:fieldset> 
 
<%
 TemplateHandler templateHandler =

TemplateHandlerRegistryUtil.getTemplateHandler(MyType.class.getName());
 %>
  
<liferay-ui:ddm-template-selector
 classNameId="<%= PortalUtil.getClassNameId(templateHandler.getClassName()) %>"
 displayStyle="<%= displayStyle %>"
 displayStyleGroupId="<%= displayStyleGroupId %>"
 refreshURL="<%= PortalUtil.getCurrentURL(request) %>"
 showEmptyOption="<%= true %>"
 /> 

</aui:fieldset>
 ...
 </aui:form>
 

4. Render templates

Last but not least, you have to extend your view code to render it with the selected ADT. Here is where you decide exactly which part of your view will be rendered by the ADT and what will be available in the template context.
 
<%
 List<MyType> myList = ...;

long ddmTemplateId = PortletDisplayTemplateUtil.getPortletDisplayTemplateDDMTemplateId(
 displayStyleGroupId, displayStyle);
 Map<String, Object> contextObjects = new HashMap<String, Object>();
 contextObjects.put("myExtraObject", someExtraObject);
 %>

<c:choose>

<c:when test="<%= portletDisplayDDMTemplateId > 0 %>">
 <%= PortletDisplayTemplateUtil.renderDDMTemplate(pageContext, ddmTemplateId, myList, contextObjects) %>
 </c:when>

<c:otherwise>
 ...
 </c:otherwise
 </c:choose>
 ...
 
Ok, has it worked for you? Try this:
  1. Add your portlet to a page
  2. Edit configuration
  3. Display Settings selector is displayed (COOL!)
  4. Click Manage Display Settings and create new ADT
  5. The template editor displays your portlet variables (GREAT!)
  6. Save and choose your new ADT
  7. The portlet is rendered with your ADT (NICE!)

 

Demo

In order to show how to integrate 6.2 new frameworks in your plugins, Sergio and Julio have created a very complete sample plugin with several portlets using the Recycle Bin, the new Staging and Search framework features... and also ADT! It's called the jukebox project. This time I decided to use the power of ADT to create a cool iTunes-like coverflow carrousel for the album covers. See the before:
And with a little bit of ADT magic...
 
... this is how it looks at the end:
 
I've shared the code of this example, but remember you'll first need to install the jukebox plugin to make it work (hold on!).
I hope you'll enjoy using ADT as much as we did when developing and testing it. Please let us know about any issue or improvement through our issue tracker and the community tools.
 
I'm running to see the next DevCon talk, see you!

 

New Ways of Customization with Application Display Templates (Part I)

General Blogs October 1, 2013 By Eduardo P. Garcia Staff

 

Next week Liferay will hold the first Developer Conference (DevCon) in Berlin. Liferay experts from all around the world will meet up to share their experience and review the latest features of version 6.2.
 
We'll have the chance to introduce Application Display Templates (ADT), a new framework to add custom display options for portlets. Juan Fernández had already given us a glipse of the power of this new tool in one of his blogs last year. This time we'll go deeper into the technical details and even show you how to support ADT in your plugins.
 
In this first part of the blog, we'll focus on how ADT works and how to use it.
 

The ADT concept

Portlet Display Settings are the simpliest way to customize portlet display.  Unlike themes or hooks, they don't require deployment and they affect specific portlet instances. But, they are limited to those that come out of the box... Wouldn’t it be great to have as many of them as we wanted? As a user, this would simplify the task of customizing the portlet display. And as developers, we wouldn’t have to change our portlet configuration code every time a new setting is required.
 
That’s exactly what Application Display Templates  (also known as ADT) provides Adding custom display settigs to our portlets. Actually, this is not a new concept in Liferay. In some portlets such as Web Content, Document and Media or Dynamid Data Lists we can add as many display options (or templates) as we want.
 

Implementation

Since we already had similar features in Liferay, we tried not to reinvent the wheel with ADT. Actually, we aimed to reuse as much logic as possible. Basically, ADT is based on two preexisting Liferay components:
  • For the service layer, we used the Dynamic Data Mapping (DDM) portlet. It manages all the operations for structures and templates in every Liferay applications.
  • We used the existing Template Engine that renders Velocity or Freemarker templates based on a given context.
So we just had to add a new portlet to the Site Administration to manage the display templates, and provide a mechanism such that any portlet can define its own template context and show its custom display settings.
 

Demo

At this point some of you may believe that ADT is too good to be true. During the DevCon we'll do a demo to show how easy it is indeed to customize a portlet display with our new tool. Here you have a preview:
 
1. Adding a new ADT for the Media Gallery
 
2. Introducing the new advanced template editor to write a Freemarker script that displays our pictures in a fancy way using the  Masonry Library
 
3. Apply our new ADT to the Media Gallery...
 
..and check the effect
 
4. Extend our template to display a tooltip with more information about the pictures and include the ratings taglib.
 
You can checkout the complete demo from gihub and try it out yourself. (You will need to install the Resource Importer plugin to get the demo contents installed).
 

Recommendations

As we have seen, ADTs bring a great power. But if there's something we've learnt, is that with great power, comes great responsability!  Let’s go through some good practices  in ADT design:
 

Security

You may want to hide some classes or packages from the template context, to limit the operations that ADTs can perform on your portal. Liferay provides some portal  properties to define the restricted classes, packages and variables:
freemarker.engine.restricted.classes 
freemarker.engine.restricted.packages
freemarker.engine.restricted.variables 
velocity.engine.restricted.classes 
velocity.engine.restricted.packages
velocity.engine.restricted.variables

Performance

ADTs add extra processing task in portlet render. This inevitably has effect in the performance. To reduce this effect, make your ADT as minimal as possible: focus on the presentation and use the existing API for complex operations. Don't forget running performance tests and tuning the template cache options:
 
 
freemarker.engine.resource.modification.check.interval velocity.engine.resource.modification.check.interval

Context

The best way to make great ADTs is to know your template context well and what you can use from it. Now you don’t need to know them by heart thanks to the advanced tempalte editor!
 

Error handling

Finally, you can improve the error handling of your templates by setting these properties:
freemarker.engine.template.exception.handler
 velocity.engine.logger
 velocity.engine.logger.category

Learn more

An this is all for the first part of the introduction to ADT. Soon we'll go through the second part: Supporting ADTs in your plugins. In the meantime you can learn more about ADT in our User Guide or promt your questions in our Forums.
 
See you in Berlin! 

 

Showing 6 results.
Items 20
of 1