Monday, March 10, 2014

Introduction to Liferay Structures and Templates

Introduction:

Structures and Templates is elegant feature in liferay web content management system. When we design web content some time we need same type of design in several places. Whenever we need such type of design and data multiple times in the web content then we will make that design as template.

Whenever we need in web content simple we will select template and we will fill with data then we can see new web content with fresh data.

Liferay have implemented this concept with two key points
  1. Structure
  2. Template

Structure:

Structure is simple xml data source which will provide dynamic data to template. This will decide what kind of data you need and what is the data design.

Let us assume I want to display image, when I want display image I need image source, width and height. So here our structure will provide required data to display image. Each time we will fill dynamic data in this structure.

Here structure is like skeleton of our body. Here skeleton have skull, chest and so on.

Note:

 Here skeleton structure may be same but for each human there is different appearance we can get different appearance based on the things we filled in skeleton.

Template:

Template will decide look and feel for structure. We can append multiple look and feel design for one structure.

We can develop template in different ways and we can use Velocity and XSLT.

Note:

Simple assume each human appearance is different even though every human skeleton structure is same.

In single word we can say structure will decide what kind of data we are going to use and template will decide look and feel for data.

Well we understand what is structure and template.

Liferay WCM management system has User Interface to create structures and templates so that we can use that to design web content with structures and templates.

When we design structure we have many options to input the data like we have text box, text, document and media and image.

We can say structure is simple xml tags which consist of predefined tags according to DTD.

Example for simple structure

<?xml version="1.0"?>
<root>
<dynamic-element name="image" type="document_library" index-type="" repeatable="false"/>
<dynamic-element name="width" type="text" index-type="" repeatable="false"/>
<dynamic-element name="height" type="text" index-type="" repeatable="false"/>
</root>

Structure View in Liferay Web content Portlet



Note:

When you see the type it will have different types (document_library,text ..)

Use Structure data in Velocity Template


<h1> simple WCM with Sturcures and Templates</h1>
<img src="$image.getData()" width="$width.getData()" height="$height.getData()"/>



Note:

Here we use getData() method on each element name to get the input data for element and in the velocity each variable start with $ symbol.


If the structure have following element

<?xml version="1.0"?>
<root>
<dynamic-element name="title" type="text" index-type="" repeatable="false"/>
</root>

Then get the title value in  templates as follows

<h1>$title.getData() </h1>




Important points:

When we design structure we have different types of elements like text, document-media, image and many

Example:


 We have option called element repeatable when we enable repeatable then we can use same element for multiples times

Example:

Assume I am going to design slide show then I may need multiple images for sidle show then I will use repeatable option for element.


In the structure we can use different levels for elements for parent element means we can define child elements.

Example:

Assume I want display image then image have some properties like width and height then we can design structure so that I will use width and height properties as child element to the image element i.e.  we can say parent element

The following is example structure with child elements



Xml Structure code for Parent and Childs

<?xml version="1.0"?>
<root>
<dynamic-element name="image" type="image" index-type="" repeatable="false">
 <dynamic-element name="height" type="text" index-type=""   repeatable="false"></dynamic-element>
 <dynamic-element name="width" type="text" index-type="" repeatable="false"/>
</dynamic-element>
</root>

Access data in Velocity (VM) Template

Get child element data

Get root element data

$image.getData()

Get image element child element

$image.height.getData()

$image.width.getData()


The final template to display Image

<img src="$image.getData()" width="$image.height.getData()" height="$image. width.getData()" alt="No Image"/>


We already know each element have repeatable option then we can add multiple data example assume I want display multiple images 

Repeatable feature



In the above image element will be repeatable so that we can add multiple images and when we use repeatable for root tag then subsequent Childs also repeated.

The following is Structure XML

<?xml version="1.0"?>
<root>
<dynamic-element name="image" type="image" index-type="" repeatable="true">
                        <dynamic-element name="height" type="text" index-type="" repeatable="false"></dynamic-element>
                        <dynamic-element name="width" type="text" index-type="" repeatable="false"/>
</dynamic-element>
</root>

When the element have repeatable feature then we will use some methods in Velocity template to access structure data


The following method  give all image elements means it collected all same level repeatable elements

$image.getSiblings()

Iterate All image elements

#foreach($currentElement in $image.getSiblings())
##write code here
#end


The following is complete Velocity Templates to display all Images


#foreach($currentImage in $image.getSiblings())

<img src="$currentImage.getData()" width="$currentImage.height.getData()" height="$currentImage. width.getData()" alt="No Image"/>

#end


When we design velocity template we can use all HTML tags and css styles to make better look and feel

The following is example

<style>
#image-container{
padding-left:10px;
font-size: 12px;
font-family: "Myriad Pro","Verdana","Arial","sans-serif";
font-size: small;
color: gray;
}
#image-container list{
list-style:none;
border:1px solid red;
}

</style>

<div "image- container " >
<ul>
#foreach($currentImage in $image.getSiblings())
<li><img src="$currentImage.getData()" width="$ currentImage.height.getData()" height="$ currentImage. width.getData()" alt="No Image"/>
</li>
#end
</ul>
<div>


The final out line


Access Structure data for elements

$elementName.getData()

Access Child element of  parent element

$parentElementName.ChidElementName.getData()

Get All siblings like when we use repeatable to element

$elementName.getSiblings()

Iterate Elements

#foreach($currentElement in $elementName.getSiblings())

##access data of current data
$currentImage.getData()

##access data of child element
$ currentElement.childElementName.getData()

#end



Use HTML and CSS in Templates

We can also use CSS styles in velocity templates so that we can give better look and feel for content.

We can use all HTML tags in velocity templates

Example Velocity Templates that contains CSS styles and HTML

<style>
#image-container{
padding-left:10px;
font-size: 12px;
font-family: "Myriad Pro","Verdana","Arial","sans-serif";
font-size: small;
color: gray;
}
#image-container list{
list-style:none;
border:1px solid red;
}

</style>

<div "image- container " >
<ul>
#foreach($currentImage in $docdowloadlinks.getSiblings())
<li><img src="$currentImage.getData()" width="$currentImage.height.getData()" height="$ currentImage. width.getData()" alt="No Image"/>
</li>
#end
</ul>
<div>

We can use styles in following ways

Tag level CSS as follows

<li><img src="$currentImage.getData()" width="$currentImage.height.getData()" height="$currentImage. width.getData()" alt="No Image" style=”border:1px solid red;”/>


Use style tag in Template

<style>
##write your styles here
</style>
<div "image- container " >
<ul>
#foreach($currentImage in $docdowloadlinks.getSiblings())
<li><img src="$currentImage.getData()" width="$currentImage.height.getData()" height="$currentImage.width.getData()" alt="No Image"/>
</li>
#end
</ul>
<div>

Use CSS link tag to load CSS

<link rel="stylesheet" type="text/css" href="/themeName/html/css/theme.css">

You can also directly use Liferay Theme level CSS classes


<div class=”custom-div”>$title.getData() </div>

Note:

We generally  define custom-div class CSS in theme custom.css file

Example:

. custom-div{
color:red;
border:1px solid red;
}


Use Java Script in Templates

We can also use java script in velocity template to perform some action or events/effects to the data.

Liferay have inbuilt Java Script library i.e. AUI so we can directly use. Simple we will use AUI use method to load required modules so that we can write java script

Whenever we write java script we will use <script> tag to place java script in templates.
Example As follows

Assume I want make alert message when I click on image

<script>
AUI().use('aui-base',function(A){
A.one("#myTemplateImage").on('click',function(){
 alert("Hi You have clicked on Template Image");
});
});
</script>
<div "image- container " >
<img src="$image.getData()" width="$image.height.getData()" height="$image. width.getData()" alt="No Image" id=”myTemplateImage”/>
<div>

We can also Load script form script src tag as follows

Assume I want use JQuery Script in Velocity Template


<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"> </script>
<script>
$(document).ready(function(){
  $("#myTemplateImage ").click(function(){
  alert("Hi You have clicked on Template Image");
  });
});
</script>
<div "image- container " >
<img src="$image.getData()" width="$image.height.getData()" height="$image. width.getData()" alt="No Image" id=”myTemplateImage”/>
<div>

Use Structures and Templates in Liferay WCM

Login as Admin and go to control panel there we can web content link in lift side panel

Create Structure

Click Structure Button and give name and description
In the structure screen you can find launch editor option select that and place following xml in editor then update.

<?xml version="1.0"?>
<root>
<dynamic-element name="image" type="image" index-type="" repeatable="true">
                        <dynamic-element name="height" type="text" index-type="" repeatable="false"></dynamic-element>
                        <dynamic-element name="width" type="text" index-type="" repeatable="false"/>
</dynamic-element>
</root>

Once you add above xml then save the structure using save button

Create Velocity Template For Structure

Now create Template using add template button enterer template name and description.

Now select required Structure using Select structure button

Now click on launch editor button and place the following velocity code in editor then click on update finally save the template.

<div "image- container " >
<ul>
#foreach($currentImage in $docdowloadlinks.getSiblings())
<li><img src="$currentImage.getData()" width="$currentImage.height.getData()" height="$currentImage. width.getData()" alt="No Image"/>
</li>
#end
</ul>
<div>

Create Web content Using Structures and Templates

Now create new web content for this click on Web content tag and select add button there you can see your template then select template

Once you select template then it will ask web content name and then based on your structure you need fill data in input fields finally save web content.

Using Web content

Now we have done all we can use that web content on web content display portlet to display images.

Note:

Whenever we need same template with different data or images then simple create another web content article so that you can see new web content with different images.

Author

Tuesday, March 4, 2014

Liferay AUI Animation Example

Introduction:

Liferay have very good java script library that AUI java script we have many modules in AUI for different use.

In the post I just explain how to use AUI animation in liferay portlet. In AUI we have some animation related java script modules from which we can do some animation for html elements.

Here AUI we have module called “anim” this will make animation for html elements.

In the anim module we have method which take animation related properties as an array of options so that we can apply animation to element

The following is simple Animation Method Syntax

var a = new A.Anim(
  {
    node: '#foo',
    to: {
        width:   100,
        height:  100,
        opacity: 0.5
    },
    duration: 0.6,
    easing: A.Easing.bounceOut
  }
);
a.run();

The following is important options

node:

This will decide on which element we need to apply animation.

to:
This is an array of option consist of width, height and opacity this will decide animation appearance.

duration:

This is the time in seconds for animation effect can be done with that time. Default value is one second.


Implementation steps

  1. We need to load required AUI modules using AUI use method
  2. Initiate animation object for specific element
  3. Use run method to apply animation upon element
Concept:

We will implement search box and here when we mouse over on search icon then we will see the search input text box to enter key words when we mouse leave then we will disappear text box so that we can see only search icon.

Screen: 1 Initial state of search or on mouse leave state



Screen: 2 on mouse over state


Note:

This is just example no server side functionality for search data.

Environment:

Liferay 6.1EE +Tomcat 7.x+MySQL 5.1

Note:

The code will work for portal 6.2 version you can try for 6.0 too because it’s just jsp page.

Download Liferay AUI Animation from following location

You can find source and war file


Procedure for deploy portlet:

You can use war file and directly place in your portal deploy folder and test or you can also use source to deploy portlet.

Once portlet is deployed successfully you can see the portlet in sample category name as LiferayAUIAnimation.

Complete Code for JSP Page

<%@ taglib uri="http://liferay.com/tld/aui" prefix="aui" %>
<%@ taglib uri="http://liferay.com/tld/portlet" prefix="liferay-portlet" %>
<%@ taglib uri="http://liferay.com/tld/security" prefix="liferay-security" %>
<%@ taglib uri="http://liferay.com/tld/theme" prefix="liferay-theme" %>
<%@ taglib uri="http://liferay.com/tld/ui" prefix="liferay-ui" %>
<%@ taglib uri="http://liferay.com/tld/util" prefix="liferay-util" %>
<%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>
<portlet:defineObjects />
<liferay-theme:defineObjects />
<style>
.searchAnimcationContainer {
display: inline-block;
position: relative;
height: 34px;
padding-left: 36px;
background-color: #9575be;
top: -6px;
z-index: 1000;
border:0px solid red;
}
.searchAnimcationContainer .searchButton {
position: absolute;
top: 0;
left: 0;
display: block;
width: 35px;
height: 35px;
}
.searchAnimcationContainer .searchInputDiv {
position: relative;
display: block;
overflow: hidden;
width: 0;
left: 1px;
text-align: left;
}
 .searchInputDiv input[type="text"] {
border: 0;
border-left: 1px solid #d5cfcf;
width: 260px;
height: 18px;
line-height: 18px;
font-size: 12px;
outline: 0;
background-color: transparent;
background: 0;
color: #fff;
font-weight:bold;
}
</style>
<portlet:actionURL var="actionURL">

</portlet:actionURL>
<div class="searchAnimcationContainer" id="searchAnimcationContainer" >
                     <form action="<%=actionURL.toString()%>" method="post" name="themeSearchForm" id="themeSearchForm">
                     <div class="searchButton" id="searchButton">
                     <a href="#">
                     <img src="<%=renderRequest.getContextPath() %>/images/btn-search.png"/>
                     </a>
                     </div>
                     <div class="searchInputDiv" id="searchInputDiv" style="width:1px;">
                     <input type="text" value="" placeholder="enter keywords" name="keywords"  id="keywords">
                     </div>
                     </form>
</div>
<aui:script>
//anim
AUI().use('aui-base','aui-node','aui-io', 'aui-event','anim', function (A) {

// intiate animation over searchInputDiv  element
              var b = new A.Anim(
                                    {
                                      node: '#searchInputDiv',
                                      duration: 0.1,
                                      easing: A.Easing.bounceOut
                                    });
                                   
              //on mouseover event so that when we movuse over on searchAnimcationContainer
              //element then animation will apply
                                   
              A.one('#searchAnimcationContainer').on('mouseenter', function(event){
             
              // define animation property array with width and opacity
                      var toArrat={width:300,opacity: 0.5};
                      b.set("to",toArrat);
                      //run animation
                      b.run();
              });
             
       //on mouseleave event so that when we mouseleave on searchAnimcationContainer element then
       //animation will apply here we will bring back animation to inti    
       A.one('#searchAnimcationContainer').on('mouseleave', function(event){
                     var toArrat1={width:1,opacity: 0.5};
                      b.set("to",toArrat1);
                     b.run();
                     b.destroy();
              });   
             
A.one('#searchButton').on('click', function(event){
document.themeSearchForm.submit();
});

  });
 
</aui:script>

Implement search functionality In theme

We will use same animation text box in theme for search and the following is steps to apply for theme.

Add following code in portal_normal.vm file (docroot\_diffs\templates\ portal_normal.vm)

<div class="righ-header-search" id="righ-header-search">
#set ($searchPortletId = "77")
#set ($searchPortletURL = $portletURLFactory.create($request, $searchPortletId, $layout.plid, "RENDER_PHASE"))
#set ($VOID1 = $searchPortletURL.setWindowState("MAXIMIZED"))
#set ($VOID1 = $searchPortletURL.setPortletMode("view"))
#set ($VOID1 = $searchPortletURL.setParameter("struts_action", "/journal_content_search/search"))
<form action="${searchPortletURL.toString()}" method="post" name="themeSearchForm" id="themeSearchForm">
<div class="searchBtn" id="searchBtn"><a href="#"><img src="$images_folder/common/btn-search.png"></a></div>
<div class="searchinput" id="searchinput" style="width:1px;">
<input class="searchinputText" type="text" value="" placeholder="enter keywords" name="keywords"  id="keywords">
</div>
</form>
</div>

Add following CSS in your theme custome.css file (\docroot\_diffs\css\ custom.css)

.righ-header-search{
display: inline-block;
position: relative;
height: 34px;
padding-left: 36px;
background-color: #9575be;
top: -6px;
z-index: 1000;
border:0px solid red;
}
.righ-header-search .searchButton {
position: absolute;
top: 0;
left: 0;
display: block;
width: 35px;
height: 35px;
}
.righ-header-search .searchBtn {
position: relative;
display: block;
overflow: hidden;
width: 0;
left: 1px;
text-align: left;
}
 .searchinput input[type="text"] {
border: 0;
border-left: 1px solid #d5cfcf;
width: 260px;
height: 18px;
line-height: 18px;
font-size: 12px;
outline: 0;
background-color: transparent;
background: 0;
color: #fff;
font-weight:bold;
}

Add following script in theme main.js (docroot\_diffs\js\main.js)

//anim
AUI().use('aui-base','aui-node','aui-io', 'aui-event','anim', function (A) {
            //search box animataion
                        var a = new A.Anim(
                                                              {
                                                                node: '#searchinput',
                                                                duration: 0.1,
                                                                easing: A.Easing.bounceOut
                                                              });
           
                        A.one('#righ-header-search').on('mouseenter', function(event){
                                     var toArrat={width:300,opacity: 0.5};
                                     a.set("to",toArrat);
                                     a.run();
                        });
                       
                                               
            A.one('#righ-header-search').on('mouseleave', function(event){
                                    var toArrat1={width:1,opacity: 0.5};
                                     a.set("to",toArrat1);
                                    a.run();
                                    a.destroy();
                        });      
           
            A.one('#searchBtn').on('click', function(event){
                        document.themeSearchForm.submit();
                        });      
  });

Note:

I have used following image
<img src="$images_folder/ common/ btn-search.png"> in portal_normal.vm file

btn-search.png image available in downloaded portlet  images directory and please  take that image and  place in your theme images/common  directory(docroot\images\common)

Theme Screen:



Note:

You may need to do small css adjustments in the css that is I have given for search box according to your theme.

Related Articles


Reference Links


Author

Recent Posts

Recent Posts Widget

Popular Posts