How to Create a New Layout Type

This article explores the extension capability provided by Liferay to create new layout types to extend the existing ones. This is a little known feature but gives a lot of power in several situations such as when building easy to use UIs for building websites for less tech-savy people, integrating external systems, etc.

Introduction and concepts #

What is a layout anyway? A layout is the name Liferay gives to each of the pages of a website. Each user and community has two websites, a public and a private one and each of this websites is formed by a set of layouts organized in a hierarchy.

Currently Liferay supports the following types of layouts:

  • Portlet: Is the original type of layout supported and allows users to put portlets in certain areas determined by a Layout Template. Liferay offers several Layout templates by default but it's also possible to create new ones.
  • Article: This type of layout shows a single content created with Liferay Journal.
  • Embedded: Shows an external website or application as a page of a Liferay website through an Iframe. It's great for quick integration of external applications. The Iframe automatically resizes to avoid unnecessary scrolling.
  • URL: This type of Layout is meant to add a link to an external resource to the website menu. Though this type of pages do not show any content of its own.
  • Link to Page (New in Liferay 4.3): It is an specialization of the previous case to make links to other pages of the same website. We will use this layout as an example to show how to create new types of layouts.

Creating a new Layout type #

Creating a new layout type is simpler that you might think. It can take from a few minutes to a few hours depending on the experience of the developer and the complexity of the edit and view page of the layout type (assuming that the backend logic, if there one is needed is already implemented).

The next sections explain the steps to create a layout type that allows a page to link to another page of the same website.

Design #

The first step in creating a new layout type is defining how are going to be their view and edit pages. In this case:

  • View: there is not going to be a view because the page will just be a link to another page. To construct the URL to the other page we'll need a parameter which identifies a layout in Liferay (which is called layoutId or plid).
  • Edit: we want to create a combo so that the user can select a page to which to link (see next image)

Next we have to determine the following properties of the new layout type:

  • Friendlability: if this layout type is subject of having friendly URLs. In this case we decide that it does not make sense because the layout will be just a link.
  • Parentability: if this layout type can become a parent by adding sublayouts underneath in the hierarchical page structure.
  • Sitemapability (new in 4.3): if this layout can ever be included in the sitemap protocol XML

Implementation #

Layout type definition #

With all the information from the design section we edit or create the portal-ext.properties configuration file, then we open the portal.properties and copy the value of the layout.types portlet into portal-ext.properties and add the name we will give to the new layout type after the existing ones:

    layout.types=portlet,embedded,article,url,link_to_layout

Next we have to describe the layout adding the following properties:

    layout.edit.page[link_to_layout]=/portal/layout/edit/link_to_layout.jsp
    layout.view.page[link_to_layout]=
    layout.url[link_to_layout]=${liferay:mainPath}/portal/layout?p_l_id=${layoutPlid}
    layout.url.friendliable[link_to_layout]=false
    layout.parentable[link_to_layout]=true
    layout.sitemapable[link_to_layout]=false

The layout.url property specifies how the portal will build the URLs on the website menu to this type of layout. The property value can use variables of the form ${variableName}. There are a few default variables (always prefixed with liferay://) that come handy when creating URLs: liferay:mainPath: includes the context of the web application ('/' by default) and the prefix used to invoke the portal Main Servlet. liferay:plid: the layout identifier of the layout instance in the database. This is the one you'll have to use when the layout type will have it's own content and will not link to an external page.

In this case we've used a custom variable called layoutPlid. The value of this variable will be given by the user when creating a new layout of this type as we'll see next.

The layout.edit.page property specifies the path to the JSP that will implement the form that will let the user choose the layout to which to link to. The fields of that form have to follow an special convention to allow Liferay Portal to automatically store them and make them available as variables to the layout.url property explained above.

The next code snippet shows a simple implementation of the form (note that you don't have to write the form tags yourself, just the field tags):

 Link to Layout (insert the layout id): 
 <input type="text" size="3" name="TypeSettingsProperties(linkToPlid)">

That's it. Note that the name of the field begis with 'TypeSettingsProperties(' and ends with a closing parenthesis ')'. In between is the name of the variable that we have defined. You can define as many variables as desired. They will all be available to the layout.url property and also to the edit and view JSPs.

An obvious necessary improvement to the above form is to show the value of variable if it has already been stored. Using struts' tags it would be:

 Link to Layout (insert the layout id): 
 <input type="text" size="3" name="TypeSettingsProperties(linkToPlid)"
         value='<bean:write name="SEL_LAYOUT" property="typeSettingsProperties(linkToPlid)"/>'>

Or, if preferred using JSP scriplet:

 <%
 Layout selLayout = (Layout)request.getAttribute(WebKeys.SEL_LAYOUT);
 %>
 Link to Layout (insert the layout id): 
 <input type="text" size="3" name="TypeSettingsProperties(linkToPlid)"
        value='<%=selLayout.getTypeSettingsProperties().getProperty("linkToPlid", "");%>'>

And that's it. The new layout type should now be fully working.

Potential improvements #

The following are further steps that could be taken to improve the simple implementation described above:

  1. Add some HTML formatting to the form
  2. Use internationalization mechanisms instead of hardcoding the text strings
  3. Building a select box with the available pages on the current website to make it easier to the user specify the layout (see screenshot above)

We'll leave all this as an exercise to the reader that can consult the result on the link to layout.jsp file in Liferay's source code.

Further possibilities #

Implementation of a layout type with a view #

The example used for this article overrides the layout.url property to change where the link in the menu goes. It is also possible to leave the URL as it is and just change the view. This is how it's done for example for the embedded layout type:

    layout.view.page[embedded]=/portal/layout/view/embedded.jsp
    layout.url[embedded]=${liferay:mainPath}/portal/layout?p_l_id=${liferay:plid}

In this case the url is left with the same value as the default and a JSP is pointed to with the implementation of the view. The actual implementation is just a few lines (removed the JS to make it easier to understand):

 <%@ include file="/html/portal/init.jsp" %>
 
    <iframe frameborder="0" height="100%" 
            src="<%= layout.getTypeSettingsProperties().getProperty("url") %>" 
            width="100%" onLoad="resizeIframe();"></iframe>
 

As you can guess the 'url' property is defined in the edit page of the layout type just as we did with the previous example with layoutPlid.

Adding common layout fields to the edit form #

As you might have been seen on some of Liferay's default layout types there are some fields that are common to all of it. This are fields for:

  • Adding Javascript to the header of the layout
  • Adding HTML meta information
  • Customizing the sitemap protocol entry for the layout (in Liferay Portal 4.3).

To include this fields in your own layout type just add the following line in the bottom of your edit JSP:

 <%@ include file="/html/portal/layout/edit/common.jsp" %>
0 Attachments
35428 Views
Average (0 Votes)
The average rating is 0.0 stars out of 5.
Comments