Liferay portal provides remote staging and publishing capability through which the users can select subsets of pages and data (both portal core assets and custom assets), and transfer them to the live site—that is, remote portal instance. Using this, we can export the selected data to the group of a remote portal instance or to another group in same portal instance.
The LAR exporting and importing features are used for remote staging and publishing. These features are implemented in the PortletDataHandler API. The intent of this API is to provide the portal core assets and custom assets with a useful API for importing and exporting application content to and from the portal in a database agnostic fashion. Abstracted from the book: Liferay Portal 5.2 Systems Development.
In addtion, the portal integrates workflow systems like jBPM or Kaleo on any assets, either core assets or custom assets; the portal provides a framework to add custom attributes or called custom fields to any Service-Builder generated entities at runtime, where indexed values, text boxes, and selection lists for input and dynamic UI are available; OpenSocial, Social Activity and Social Equity are available in Plugins; and CAPTCHA or reCAPTCHA would be available for custom assets; etc. As mentioned in following blogs posts, these features have been applied on custom assets in plugins.
- Integrating CAPTCHA or reCAPTCHA with custom assets through plugins
- Adding Social Equity services on custom assets through plugins
- Adding Custom Attributes capabilities on custom assets in Liferay 6 through plugins
- How to add workflow capabilities on Knowledge Base articles or any custom assets in plugins
- Applying workflow on custom assets in Liferay 6 through plugins
When applying LAR and remote publishing capabilities on custom assets, following use cases come into picture.
- Use case A: ability to archive custom assets, for example, Knowledge Base articles.
- Use case B: ability to publish custom assets from staging to live remotely.
This article will address how to implement LAR and remote publishing capabilities on custom assets, for example knowledge base articles, in plugins. Of course, you can leverage the same mechanism to apply LAR and remote publishing capabilities on your own custom assets.
LAR – import and export
Data export and import generally revolve around the concept of storing data outside the portal permanently or temporarily. The portal does this by handling the creation and interpretation of the LAR files. The functions of data export and import are portlet-wise. Following screenshot shows capabilities to import and export Knowledge base articles.
Note that LAR is short for Liferay Archive. It includes all of the pages, their layouts, their configurations, their look and feel, their permissions, and so on. Importing a LAR file will overwrite any existing pages of a given group configured in the LAR file. And most importantly, target portal server, which is used to import LAR file, must have exactly same version as that of source portal server, which is used to export LAR file. That is, LAR should not be used for upgrade.
Custom Asset models – Knowledge Base
As shown in following figure, Knowledge Base articles are specified as entries: Article, Comment, and Template. The entry Article included columns: article Id as primary key, resource Prim Key, group Id, company Id, user Id, user Name, create Date, modified Date, parent resource Prim Key, version, title, content, description, priority, and so on; the entry Template included columns: template Id as primary key, group Id, company Id, user Id, user Name, create Date, modified Date, title, content, description and so on; while the entity Comment included columns: comment Id as primary key, group Id, company Id, user Id, user Name, create Date, modified Date, class Name Id, class PK, content, helpful, and more. As you can see, the entity Comment could be applied on either any core assets or custom assets like Article and Template by using class Name Id and class PK.Sure, you can find details in $PLUGIN_SDK_HOME/knowledge-base-portlet/docroot/WEB-INF/service.xml
Abstracted from the book: Liferay User Interface Development
When exporting / importing custom assets like knowledge base articles, first above models and their versions should be in picture. And moreover, following associations should be taken into account.
- Attachments (as documents)
- Documents (as links)
- Images (if any)
- Polls (if any)
- Asset ratings
- Asset view counts
- Asset comments and votes on comments
- Subscriptions
- Addresses (if any)
- Asset tags
- Asset categories
- Custom fields
- Locks
- Permissions
Solution Overview
Following diagram shows what’s happening to remote publish on custom assets. Supposed that there is one staging server – one Liferay installation for internal users to build and review web content, and there is one remote live server - one Liferay installation for external users to view web content. Of course, you can have more than one live servers clustered.
By the way, the portal provides capabilities to have local staging and local live, that is, the live group and the staging group exist in the same portal instance. How does it work? You can refer to the book: Liferay Portal 5.2 Systems Development.
In general, there are three-step processes to remote publish assets, both core assets and custom assets.
- Export assets – both core assets and custom assets – as internal LAR in staging server
- Push exported LAR from Staging to Remote Live server through tunnel-web, both staging server and remote live server
- Import assets - both core assets and custom assets – as internal LAR in remote live server;
Protecting tunnel servlet
Of course, you need to protect tunnel servlet. In order to communicate with the remote server and, moreover, protect HTTP connection, we need to set up a tunnel web in portal-ext.properties. That is, add the following lines at the end of portal-ext.properties:
tunnel.servlet.hosts.allowed=127.0.0.1,69.198.171.104,69.198.171.105,64.71.191.145,SERVER_IP
tunnel.servlet.https.required=false
The preceding code shows a tunnel.servlet.hosts.allowed property with a list of allowed hosts, for example, 69.198.171.104, 69.198.171.105, and 64.71.191.145 – IPs of staging server and remote live servers, replacing them with IPs of your own servers. As stated above, we used these hosts as examples only. You can have your own real hosts. Meanwhile, it specifies the tunnel.servlet.https.required property. By default, it is set as a false value. You can set it as a true value if you want to use HTTPS.
Capabilities
Note that remote publishing function should be used to push content only – both staging server and remote servers must have exactly same version. That is, remote publishing feature should not be used for upgrade.
How to Implement LAR?
In following three steps, you should be able to implement LAR to archive knowledge base articles.
- Add portlet-data-handler in $PLUGIN_SDK_HOME/knowledge-base-portlet/docroot/WEB-INF/liferay-portlet.xml like
<portlet-data-handler-class>com.liferay.knowledgebase.admin.lar.AdminPortletDataHandlerImpl</portlet-data-handler-class>
- Extend com.liferay.portal.kernel.lar.BasePortletDataHandler as com.liferay.knowledgebase.admin.lar.AdminPortletDataHandlerImpl.
Note that com.liferay.portal.kernel.lar.BasePortletDataHandler implements com.liferay.portal.kernel.lar.PortletDataHandler. Thus we can say, com.liferay.knowledgebase.admin.lar.AdminPortletDataHandlerImpl implements com.liferay.portal.kernel.lar.PortletDataHandler.
com.liferay.portal.kernel.lar.PortletDataHandler has following interface.
public interface PortletDataHandler {
public PortletPreferences deleteData(PortletDataContext portletDataContext, String portletId, PortletPreferences portletPreferences) throws PortletDataException;
public String exportData(PortletDataContext portletDataContext, String portletId,PortletPreferences portletPreferences) throws PortletDataException;
public PortletDataHandlerControl[] getExportControls() throws PortletDataException;
public PortletDataHandlerControl[] getImportControls() throws PortletDataException;
public PortletPreferences importData(PortletDataContext portletDataContext, String portletId, PortletPreferences portletPreferences, String data) throws PortletDataException;
public boolean isAlwaysExportable();
public boolean isPublishToLiveByDefault();
}
com.liferay.portal.kernel.lar.BasePortletDataHandler has following interfaces:
public PortletPreferences deleteData(
PortletDataContext portletDataContext, String portletId,PortletPreferences portletPreferences)
public String exportData(
PortletDataContext portletDataContext, String portletId,PortletPreferences portletPreferences)
public PortletDataHandlerControl[] getExportControls()
public PortletDataHandlerControl[] getImportControls()
public boolean isAlwaysExportable()
public boolean isPublishToLiveByDefault()
public PortletPreferences importData(
PortletDataContext portletDataContext, String portletId,
PortletPreferences portletPreferences, String data)
protected PortletPreferences doDeleteData(
PortletDataContext portletDataContext, String portletId,PortletPreferences portletPreferences)
protected String doExportData(
PortletDataContext portletDataContext, String portletId, PortletPreferences portletPreferences)
protected PortletPreferences doImportData(
PortletDataContext portletDataContext, String portletId,PortletPreferences portletPreferences, String data)
- Implement methods doDeleteData(), doExportData() and doImportData() in com.liferay.knowledgebase.admin.lar.AdminPortletDataHandlerImpl.
In method doDeleteData(), remove articles, comments and templates by group.
in methods doExportData() and doImportData(), export / import following items:
custom assets: Articles, Comments, Templates
custom assets’ associations: attachments (as documents), images (if any), polls (if any), asset rating, asset view counts, asset comments and votes on comments, subscriptions, address (if any), asset tags, asset categories, custom fields, permissions, etc.
That's it. This is useful, isn’t it?
Summary
In brief, import/export and remote publishing features are available for custom assets in plugins. You can use import/export feature to archive your custom assets (Use case A), and remote publishing feature to push custom assets from staging server to remote live servers with one simple click (Use case B). Especially, you can schedule remote publish processes as well. Let’s address scheduling feature later.
By the way, you can have a closer look at the knowledge base source code (revision 69840) with LAR and remote publishing features in
knowledge-base-portlet-6.1.0.1.war
Last but not least, I'd like to send a ton of thanks to Liferay development team and Liferay community, who made a lot of good stuff.


