Layout Template – Liferay 6.2

The Liferay CMS provides built-in layout templates which are sufficient for most of the requirements of a portal page. Sometimes we may need to design a custom page template that meets our requirements. We can achieve this with the Liferay layout template plugin.

In this article, we will learn about the Liferay layout templates and how to create custom layout templates.

Version details: Liferay 6.2

Creating the liferay layout template

We will use the Liferay Developer Studio(LDS) IDE to create the Liferay layout template.

Create a new plugin project from File >> New >> Liferay Plugin Project. Enter the project name, select the plugin type as Layout Template, and click on the Finish button.

layoutTemplate1.PNG

The below image shows the folder structure of the Liferay layout template.

layoutTemplate2

A few of the files of the Liferay layout template project are listed below.

  • liferay-layout-templates.xml: This is the file that specifies the name and the location of the template files. The file also specifies the thumbnail image location.
  • projectname.tpl : Generates the HTML structure(myLayoutTemplate.tpl).
  • projectname.wap.tpl : Generates the HTML structure for mobile devices(myLayoutTemplate.wap.tpl).
  • projectname.png : The thumbnail image for layout template in the .png format(myLayoutTemplate.png).
  • liferay-plugin-package.properties : Defines the plugin project properties.

Designing the layout template

Initially, the generated layout template project files are empty.

With the Liferay IDE, we can use the default layout templates as a reference and modify them according to our requirements.

We can select the design mode of the .tpl file to add the available sample design to our template file while using the LDS IDE.

Designing the custom template

To create the template structure manually, open the .tpl file, add an element as shown below. The element should include classid, and role attributes.

Also, the element value of the <div> tag’s id attribute value should be “main-content” and the role attribute value as “main“. The class attribute can be any custom value.

< div class="myLayoutTemplate" id="main-content" role="main">
 ...
</div>

To add a row, add an element inside the created element, as shown below. The element class attribute value should be “portlet-layout row-fluid”.

< div class="portlet-layout row-fluid">
 ...
</div>

To add the layout columns, add an <div> element for each column inside the layout row element as shown below. Each column should have a unique ID attribute.

The convention is to use the id value with the format column-x, where x is an integer in the incremental order.

< div class="portlet-column portlet-column-only span12" id="column-1">
    ...
</div>

Each column must specify the CSS class called portlet-column.

If a column is a first column or the last column, or the only column in a row, that column must use either the portlet-column-firstportlet-column-last or the portlet-column-only CSS class, respectively.

Each column’s class attribute must also specify a CSS class called the span[width], where the width can be in the range 1 to 12(In the Liferay 6.2 layout, templates use Bootstrap’s 12 column grid system).

Finally, with each column element, you must include a Velocity template directive to render each of the column’s portlets, as shown below.

$processor.processColumn("column-1",
 "portlet-column-content portlet-column-content-first")

The above method takes two arguments, the column id and the list of CSS classes.

The CSS class attribute value “portlet-column-content” must be passed as the second argument of the above method.

If the column is the first, last, or only column in a row, we have to pass both the portlet-column-content and the portlet-column-content-[first|last|only] in the second argument, separated by a space.

Complete liferay template code

The complete code for a 1-3-1 Liferay layout template is given below.

< div class="myLayoutTemplate" id="main-content" role="main">
 < div class="portlet-layout row-fluid">
 < div class="portlet-column portlet-column-only span12" id="column-1">
  $processor.processColumn("column-1", "portlet-column-content portlet-column-content-only")
 </div>
 </div>

 < div class="portlet-layout row-fluid">
 < div class="portlet-column portlet-column-first span4" id="column-2">
  $processor.processColumn("column-2", "portlet-column-content portlet-column-content-first")
 </div>

 < div class="portlet-column portlet-column-last span4" id="column-3">
  $processor.processColumn("column-3", "portlet-column-content portlet-column-content-only")
 </div>
 
 < div class="portlet-column portlet-column-last span4" id="column-4">
  $processor.processColumn("column-4", "portlet-column-content portlet-column-content-last")
 </div>
 </div>

 < div class="portlet-layout row-fluid">
 < div class="portlet-column portlet-column-only span12" id="column-5">
   $processor.processColumn("column-5", "portlet-column-content portlet-column-content-only")
 </div>
 </div>
</div>

Finally, below is the created Liferay template design.

layoutTemplate3

Embedding portlets to the layout template

To embed portlet to Liferay template, we need the following attributes.

  • portlet id : This is the value of the tag of the portlet.xml file. For core portlets, check the file liferay-portal/portal-web/docroot/WEB-INF/liferay-portlet.xml
  • Instanceable: Specify whether multiple instances of the portlet can exist in the portal. This is specified with the keyword _INSTANCE_xxxx where XXXX is a random alphanumeric value. A custom instantiable portlet’s value may look like: portletID_WAR_webAppContext_INSTANCE_instanceID
  • Web Application Context: Web context name of the portlet.

We also need to pass the fully qualified portlet id and we can copy this from the advanced styling section of the custom plugin portlets.

The below is an example implementation.

//Core portlet(Search):
$processor.processPortlet("3")

//Instanceable core portlet(Navigation):
$processor.processPortlet("71_INSTANCE_abc8")

//Custom Portlet:
$processor.processPortlet("myCustomPortlet_WAR_myCustomPortletportlet_INSTANCE_abc1")

//Instanceable custom portlet:
$processor.processPortlet("myCustomPortlet_WAR_mycustomportlet_INSTANCE_abc1")

Finally, the complete code of the Liferay layout template implementation is listed below.

< div class="myLayoutTemplate" id="main-content" role="main">
 < div class="portlet-layout row-fluid">
 < div class="portlet-column portlet-column-only span12" id="column-1">
   $processor.processColumn("column-1", "portlet-column-content portlet-column-content-only")
 </div>
 </div>

 < div class="portlet-layout row-fluid">
 < div class="portlet-column portlet-column-first span4" id="column-2">
   $processor.processPortlet("3")
   $processor.processColumn("column-2", "portlet-column-content portlet-column-content-first")
 </div>

 < div class="portlet-column portlet-column-last span4" id="column-3">
   $processor.processPortlet("71_INSTANCE_abc8")
   $processor.processColumn("column-3", "portlet-column-content portlet-column-content-only")
 </div>
 
 < div class="portlet-column portlet-column-last span4" id="column-4">
   $processor.processPortlet
   ("myCustomPortlet_WAR_myCustomPortletportlet_INSTANCE_abc1")
   $processor.processColumn("column-4", "portlet-column-content portlet-column-content-last")
 </div>
 </div>

 < div class="portlet-layout row-fluid">
 < div class="portlet-column portlet-column-only span12" id="column-5">
   $processor.processPortlet("AB_WAR_ABportlet")
   $processor.processColumn("column-5", "portlet-column-content portlet-column-content-only")
 </div>
 </div>
</div>

Testing the output

Deploy the created custom Liferay layout template and apply the template to the portal page.

The below image shows the portal page that uses our custom template layout.

layoutTemplate4

Conclusion

In this article, we learned about the Liferay layout template.

We also learned how to create a custom Liferay layout template.

Finally, we applied our custom Liferay layout template to the portal page.