Note: This document is part of the Liferay Core Development Guidelines

Introduction #

This article describes the rules, conventions and tools used to build Liferay's UI. The goals for documenting them are:

  • Provide a consistent API to the users
  • Conform to the latest web standards
  • Reduce UI development time by providing documented UI components
  • Use a limited set of tools to simplify the code base

Usage of HTML and CSS #

General rules:

  • Use semantic HTML:
    • Proper use of HTML tags: P, LI, TABLE, etc
    • Add classes to make the HTML themable
  • Generate XHTML compliant markup

Forms #

Use UniForm to make the forms good looking and themable.

Disclaimer: Not all of the forms in Liferay's portlets use UniForm yet, but we are rapidly moving towards it.

The main classes that should be added are:

  • uni-form: should be used in the form tag
  • block-labels (recommended) or inline-labels: to control if labels are above or to the left of the form fields. I usually applied to the fieldset tag.
  • ctrl-holder: contains a label the associated form field. It's usually applied to a div element.
  • button-holder: contains groups of buttons. It's usually applied to a div element.

Other things to note are:

  • Use fieldsets to group related fields
  • For fields of type 'radio' include the input element inside the label element (see example below)

Let's go over the main aspects of uniform by visiting a real example: the Web Form portlet (some things removed for simplicity):

 <form action="..." class="uni-form" method="post">
 <fieldset class="block-labels">
   <legend><%= title %></legend>
   
      <label for="<portlet:namespace /><%= fieldName %>"><%= fieldLabel %></label>	
      <input name="<portlet:namespace /><%= fieldName %>" 
             type="text" 
             value="<%= fieldValue %>" />
   
   
      <label>
          <input type="radio" name="<portlet:namespace /><%= fieldName %>" 
                 <%= fieldValue.equals(options[j]) ? "checked=\"true\"" : "" %> 
                 value="<%= options[j] %>" /> 
          <%= options[j] %>
       </label>
   
   
     <input type="submit" value="<liferay-ui:message key="send" />" />
   
  </fieldset>
  </form>

Using the CSS Class wrapper #

The CSS class wrapper can be configured for a portlet to create CSS selectors that apply only to the elements of that portlet. It is set through the portlet entry in the liferay-portlet.xml file. For example:

 <css-class-wrapper>portlet-mail</css-class-wrapper>

Now it's possible to style all the paragraphs of that portlet using:

 .portlet-mail p {
    ...
  }

Predefined CSS Classes #

  • lfr-fallback: display this element only if javascript is not supported or not activated
  • float-container: allow adding float elements inside of this element and ensuring that it will have a height that will properly wrap around the objects
  • separator: apply to a div element to add a nice horizontal line. Add a comment inside the the div to ensure proper behavior in IE.
  • lfr-component: applied to HTML list elements to remove their default styling (padding, bullet points, etc.)

Rules for defining new CSS classes #

Apply the following rules when defining new class names within Liferay's portlets:

  • Use a class name that describes the purpose of the element, not the style you are to give it.
  • Separate words with dashes
  • Try to keep class names to less than 3 words (4 at the very most)
  • Start the class name with the prefix 'portlet-{portletName}' for example 'portlet-wiki'
    • Note: this may change in the near future, because thanks to the new CSS class wrappers the prefix is no longer necessary

Usage of JavaScript #

As of versions 6 and forward, Liferay uses AlloyUI, a custom JS library built on Yahoo User Interface (YUI). For more information, see Alloy UI.

Introduction to jQuery #

As of versions 4.3 and 4.4, the Liferay Portal uses jQuery 1.1.4 as it's base Javascript framework. Using jQuery is simple for both advanced Javascript users, as well as Javascript novices.

jQuery uses the concept of CSS selectors (#banner, .tree-item or even body > #wrapper) to grab elements on a page and manipulate them.

While explaining jQuery's usage in full detail is out of the scope of this document, there is a vibrant community surrounding jQuery, as well as very detailed documentation.

To quickly give you an idea of what is possible in jQuery, and how it can save you lines of code, and increase code legibility, here is a compare and contrast between the jQuery method and the traditional way of manipulating the page:

Examples of jQuery #

Checking all unchecked checkboxes#

Traditional:

 var inputs = document.getElementsByTagName('input');
 for(var i = 0; i < inputs.length; i++){
    if (inputs[i].type == 'checkbox' && inputs[i].checked == false) {
       inputs[i].checked = true;
    }
 }

jQuery:

 jQuery('input[@type=checkbox]').not(':checked').attr('checked', true);

Toggling the visibility of an element#

Traditional:

 var div = document.getElementById('banner');
 if (div.style.display == 'none' || div.style.visibility == 'hidden') {
    div.style.display = 'none';
 }
 else {
    div.style.display = 'block';
 }

jQuery:

 jQuery('#banner').toggle();

Removing all paragraphs with a class of content#

Traditional:

 var p = document.getElementsByTagName('p');
 for(var i = 0; i < ENTER_CRITERIA; i++){
        if (p[i].className == 'content') {
                p[i].parentNode.removeChild(p[i]);
        }
 }

jQuery:

 jQuery('p.content').remove();

AJAX#

jQuery has replaced some of the Liferay code, such as the legacy AjaxUtil. So instead of doing this:

 AjaxUtil.update('file.jsp', 'divId');

You should do this:

 jQuery('#divId').load('file.jsp');

But not only that, you can do extensive AJAX connections, with a simple and formalized API that is intuitive and easy to use.

Very flexible and easy to use is this method (see jQuery#ajax):

jQuery.ajax({   
	type: "POST",
	url: "file.jsp",
	data: "param1=value1&param2=value2",
	success: function(){			
	}
});

Notes about jQuery in Liferay #

We use jQuery in "no conflict" mode. By default, jQuery is assigned to the $ variable, which is how you will see it referenced in the jQuery documentation. However, when in no conflict mode, the $ is not used, as it may cause conflict with other libraries that use the same variable. Instead, when in no conflict mode, use this: jQuery('.selector') instead of this: $('.selector').

Also, because we're using version 1.1.4 instead of the latest (1.2), there may be a few methods that their documentation refers to that are not currently supported.

We plan on upgrading in the next few months.

Use the available API #

Use the available API whenever possible. That includes jQuery, jQuery's included plugins and the own API by Liferay. All of it is documented in Liferay JavaScript API

UI Components #

Several UI components are provided through the liferay-ui taglib.

0 附件
62660 查看
平均 (0 票)
满分为 5,平均得分为 0.0。
评论
讨论主题回复 作者 日期
Link to UniForm website is not correct. Now is... Pier Paolo Ramon 2010年12月1日 上午2:34

Link to UniForm website is not correct. Now is http://sprawsm.com/uni-form/

PS: Liferay syntax does not reflect new Camel form syntax adopted by uni-form
在 10-12-1 上午2:34 发帖。