Customizing Page Management in Liferay Portal 5.2 Systems Development

Exclusive offer: get 50% off this eBook here
Liferay Portal 5.2 Systems Development

Liferay Portal 5.2 Systems Development — Save 50%

Liferay Portal 5.2 Systems Development

$32.99    $16.50
by Jonas X. Yuan | May 2009 | Java

In this article by Jonas Yuan, we'll see how to employ features of page management. We will also learn how to use communities and layout pages efficiently.

Customizing page management with more features

The Ext Manage Pages portlet not only clones the out of the box Manage Pages portlet, but it also extends the model and service — supporting customized data, for example, Keywords. We can make these Keywords localized too.

 

Adding localized feature

Liferay portal is designed to handle as many languages as you want to support. By default, it supports up to 22 languages. When a page is loading, the portal will detect the language, pull up the corresponding language file, and display the text in the correct language.

We want the Keywords to be localized too. For example, the default language is English (United States) and the localized language is Deutsch (Deutschland). Thus, you have the ability to enter not only the Name and HTML Title in German, but also the Keywords in German.

As shown in the following screenshot, when you change the language of the page in German using the language portlet, you will see the entire web site changed to German, including the portlet title and input fields. For example, the title of the portlet now has the Ext Seiteneinstellungen value and the Keywords now become Schlüsselwörter.

How do we implement this feature? In other words, how do we customize the language display in the page management? Let's add the localized feature for the Ext Manage Pages portlet.

Liferay Portal 5.2 Systems Development

Extending model for locale

First of all, we need to extend the model and to implement that model in order to support the localized feature. For the ExtLayout model, let's add the locale method first.

  1. Locate the ExtLayout.java file from the com.ext.portlet.layout.model package in the /ext/ext-service/src folder, and open it.
  2. Add the following lines before the line } in ExtLayout.java and save it:
      public String getKeywords(Locale locale);
      public String getKeywords(String localeLanguageId);
      public String getKeywords(Locale locale,
      boolean useDefault);
      public String getKeywords(String localeLanguageId,
      boolean useDefault);
      public void setKeywords(String keywords, Locale locale);

As shown in the code above, it adds getting and setting methods for the Keywords field with locale features. Now let's add the implementation for the ExtLayout model:

  1. Locate the ExtLayoutImpl.java file from the com.ext.portlet.layout.model.impl package in the /ext/ext-impl/src folder and open it.
  2. Add the following lines before the last } in ExtLayoutImpl.java file and save it:
      public String getKeywords(Locale locale) {
      String localeLanguageId = LocaleUtil.toLanguageId(locale);
      return getKeywords(localeLanguageId);
      }
      public String getKeywords(String localeLanguageId) {
      return LocalizationUtil.getLocalization(getKeywords(),
      localeLanguageId);
      }
      public String getKeywords(Locale locale, boolean useDefault) {
      String localeLanguageId = LocaleUtil.toLanguageId(locale);
      return getKeywords(localeLanguageId, useDefault);
      }
      public String getKeywords(String localeLanguageId, boolean
      useDefault) {
      return LocalizationUtil.getLocalization( getKeywords(),
      localeLanguageId, useDefault);
      }
      public void setKeywords(String keywords, Locale locale) {
      String localeLanguageId = LocaleUtil.toLanguageId(locale);
      if (Validator.isNotNull(keywords)) {
      setKeywords(LocalizationUtil.updateLocalization(
      getKeywords(), "keywords", keywords, localeLanguageId));
      }
      else {
      setKeywords(LocalizationUtil.removeLocalization(
      getKeywords(), "keywords", localeLanguageId));
      }
      }

As shown in the code above, it adds implementation for get and set methods of the ExtLayout model.

Customizing language properties

Language files have locale-specific definitions. By default, Language.properties (at /portal/portal-impl/src/content) contains English phrase variations further defined for United States, while Language_de.properties (at /portal/portal-impl/src/content) contains German phrase variations further defined for Germany. In Ext, Language-ext.properties (available at /ext/ext-impl/src/content) contains English phrase variations further defined for United States, while Language-ext_de.properties (should be available at /ext/ext-impl/src/content) contains German phrase variations further defined for Germany.

First, let's add a message in Language-ext.properties, by using the following steps:

  1. Locate the Language-ext.properties file in the /ext/ext-impl/src/content folder and open it.
  2. Add the following line after the line view-reports=View Reports for Books and save it.
      keywords=Keywords

This code specifies the keywords message key with a Keywords value in English:

Then we need to add German language feature in Language-ext_de.properties as follows:

  1. Create a language file Language-ext_de.properties in the /ext/ext-impl/src/content folder and open it.
  2. Add the following lines at the beginning and save it:
    ## Portlet names
    javax.portlet.title.EXT_1=Berichte
    javax.portlet.title.jsp_portlet=JSP Portlet
    javax.portlet.title.book_reports=Berichte für das Buch
    javax.portlet.title.extLayoutManagement=Ext Seiteneinstellungen
    javax.portlet.title.extCommunities=Ext Communities
    ## Messages
    view-reports=Ansicht-Berichte für Bücher
    keywords=Schlüsselwörter
    ## Category titles
    category.book=Buch
    ## Model resources
    model.resource.com.ext.portlet.reports.model.ReportsEntry= Buch ## Action names
    action.ADD_BOOK=Fügen Sie Buch hinzu

As shown in the code above, it specifies the same keys as that of Language-ext.properties. But all the keys' values were specified in German instead of English. For example, the message keywords has a Schlüsselwörter value in German.

In addition, you can set German as the default language and Germany as the default country if it is required. Here are the simple steps to do so:

  1. Locate the system-ext.properties file in the /ext/ext-impl/src folder and open it.
  2. Add the following lines at the end of system-ext.properties and save it:
      user.country=DE
      user.language=de

The code above sets the default locale — the language German (Deutsch) and the country Germany (Deutschland). In general, there are many language files, for example Language-ext.properties and Language-ext_de.properties, and some language files would overwrite others in runtime loading. For example, Languageext_de.properties will overwrite Language-ext.properties when the language is set as German.

These are the three simple rules which indicate the priorities of these language files:

  1. The ext versions take precedence over the non-ext versions.
  2. The language-specific versions, for example _de, take precedence over the non language-specific versions.
  3. The location-specific versions, such as -ext_de, take precedence over the non location-specific versions.

For instance, the following is a ranking from bottom to top for the German language:

  1. Language-ext_de.properties
  2. Language_de.properties
  3. Language-ext.properties
  4. Language.properties
Liferay Portal 5.2 Systems Development Liferay Portal 5.2 Systems Development
Published: May 2009
eBook Price: $32.99
Book Price: $54.99
See more
Select your format and quantity:

Displaying multiple languages

In order to support multiple languages, we have to update the updateLayout method at AddLayoutLocalServiceUtil under the com.ext.portlet.layout.action package of ext/ext-impl/src. To do so, add the following lines before the last }:

protected static void setLocalizedAttributes(ExtLayout extLayout, 
Map<Locale, String> localeKeywordsMap) {
Locale[] locales = LanguageUtil.getAvailableLocales();
for (Locale locale : locales) {
String keywords = localeKeywordsMap.get(locale);
extLayout.setKeywords(keywords, locale);
}
}

As shown in the code above, it added the locale feature method setLocalizedAttributes. Now, update the line String keywords = ParamUtil.getString(actionRequest, "keywords"); with the following lines in the updateLayout method of AddLayoutLocalServiceUtil:

Locale[] locales = LanguageUtil.getAvailableLocales();
Map<Locale, String> localeKeywordsMap = new HashMap<Locale,
String>();
for (Locale locale : locales) {
String languageId = LocaleUtil.toLanguageId(locale);
localeKeywordsMap.put( locale,
ParamUtil.getString(actionRequest, "keywords_" + languageId));
}

Further, update the line extLayout.setKeywords(keywords); with the line setLocalizedAttributes(extLayout, localeKeywordsMap); in the updateLayout method of AddLayoutLocalServiceUtil.

Finally, we need to update the JSP file edit_pages_page.jsp for the localized feature. To do so, first update the lines <td><liferay-ui:input-field model="<%=ExtLayout.class %>" bean="<%= extLayout %>" field="keywords" /></td><td></td> with the following lines:

<td>
<input id="<portlet:namespace />keywords_<%= defaultLanguageId %>"
name="<portlet:namespace />keywords_<%= defaultLanguageId %>"
size="30" type="text"
value="<%= extLayout.getKeywords(defaultLocale) %>" />
</td>
<td>
<% for (int i = 0; i < locales.length; i++) {
if (locales[i].equals(defaultLocale)) {
continue;
} %>
<input id="<portlet:namespace />keywords_<%=
LocaleUtil.toLanguageId(locales[i]) %>"
name="<portlet:namespace />keywords_<%=
LocaleUtil.toLanguageId(locales[i]) %>"
type="hidden" value="<%= extLayout.getKeywords(locales[i],
false) %>" />
<% } %>
<input id="<portlet:namespace />keywords_temp"
size="30"
type="text"
<%= currentLocale.equals(defaultLocale) ? "style='display:
none'" : "" %>
onChange="<portlet:namespace />onKeywordsChanged();" />
</td>

Then add the following lines after the line var lastLanguageId = "<%=currentLanguageId %>"; in edit_pages_page.jsp:

var keywordsChanged = false;
function <portlet:namespace />onKeywordsChanged() {
keywordsChanged = true;
}

As shown in the code above, it adds the locale feature for the keywords field. It also updates JavaScript for the onKeywordsChanged() method. From now on, the Ext Manage Pages portlet has a locale feature (German, for example) on the customized field, keywords.

Moreover, add the following lines after the lines jQuery("#<portlet:namespace />title_" + lastLanguageId).attr("value", titleValue); titleChanged = false; } of the JavaScript method function <portlet:namespace/>updateLanguage() in the edit_pages_page.jsp file:

if (keywordsChanged) {
var keywordsValue = jQuery("#<portlet:namespace />
keywords_temp").attr("value");
if (keywordsValue == null) {keywordsValue = "";}
jQuery("#<portlet:namespace />keywords_" +
lastLanguageId).attr("value", keywordsValue);
keywordsChanged = false;
}

Add the line jQuery("#<portlet:namespace />keywords_temp").show(); after the line jQuery("#<portlet:namespace />title_temp").show();. Add the line jQuery("#<portlet:namespace />title_temp").hide(); after the line jQuery("#<portlet:namespace />keywords_temp").hide(); of the function<portlet:namespace />updateLanguage() method in edit_pages_page.jsp:

Last but not the least, we need to update the function <portlet:namespace />updateLanguageTemps(lang) method in edit_pages_page.jsp. To do so, first add the following lines after the line var defaultTitleValue =n jQuery("#<portlet:namespace />title_<%= defaultLanguageId %>").attr("value");

var keywordsValue = jQuery("#<portlet:namespace />keywords_" + 
lang).attr("value");
var defaultKeywordsValue = jQuery("#<portlet:namespace />keywords_<%=
defaultLanguageId %>").attr("value");
if (defaultKeywordsValue == null) { defaultKeywordsValue = "";}

Now, add the following lines after the line else { jQuery("#<portlet:namespace/>title_temp").attr("value", titleValue); }:

if ((keywordsValue == null) || (keywordsValue == "")) {
jQuery("#<portlet:namespace />keywords_temp").attr("value",
defaultKeywordsValue);
}
else {
jQuery("#<portlet:namespace />keywords_temp").attr("value",
keywordsValue); }

As shown in the code above, it specifies variables keywordsValue anddefaultKeywordsValue. It then uses JQuery to update the states of the attribute, for example, #<portlet:namespace />keywords_temp.

Employing tabs

As shown in the following screenshot, we expect to add one customized Layout tab beside the Look and Feel tab. When this tab is selected, it will print the current value, for example, tabs3Names = page,children,look-and-feel,layout.

Liferay Portal 5.2 Systems Development

Let's employ the tabs in the Ext Manage Pages portlet. First, update the filter of JSP file edit_pages.jsp at /ext/ext-web/docroot/html/portlet/ext/communities. To do so, add && !tabs3.equals("layout") after if (tabs2.equals("pages") && ((!tabs3.equals("children") && !tabs3.equals("look-and-feel") as follows:

if (tabs2.equals("pages") && ((!tabs3.equals("children") && !tabs3.
equals("look-and-feel") && !tabs3.equals("layout")) || ((selLayout !=
null) && !PortalUtil.isLayoutParentable(selLayout)))) {

As shown in the code above, it allows the tab value layout available for tabs3 as well as for the values children and look-and-feel.

Then, add the Layout tab and a value in the JSP file edit_pages_public_and_private.jspf at /ext/ext-web/docroot/html/portlet/ext/communities. To do so, first replace tabs3Names += ",look-and-feel"; with tabs3Names += ", look-and-feel,layout"; as follows:

if ((selLayout != null) && (permissionChecker.isOmniadmin() || 
PropsValues.LOOK_AND_FEEL_MODIFIABLE)) {
tabs3Names += ",look-and-feel,layout";
}

Then, add the following lines before the last </c:choose> tag:

<c:when test='<%= tabs3.equals("layout") %>'>
tabs3Names = <%= tabs3Names %>
</c:when>

As shown in the code above, it adds a Layout tab when the Look and Feel tab is added. If the value was layout, it prints the current value of tabs3Names.

In short, the portal can include custom tabs that allow you to create the same look and feel as that of the out of the box tabs in your own portlets. These tabs would essentially be just other JSP pages, and be displayed based on the selection of custom tabs.

Applying layout templates dynamically

As stated above, we have added the Layout tab in the Ext Manage Pages portlet. Now let's apply the layout templates dynamically under this tab. Further, the portal comes with several built-in layout templates. Layout templates are the ways of choosing how your portlets will be arranged on a page. They make up the body of the page - the large area where you can drag and drop your portlets to create your pages.

Why do we need this feature? It is great for developers or CMS administrators to manually create pages using the drag-and-drop feature. But for some content creators and content producers, the drag-and-drop functions would be amazing but difficult to use. Thus they expect the layout templates to be created by the CMS admin only. Then they only view the possible layout templates for pages, apply layout templates dynamically, and populate the content of pages if applicable.

As shown in the following screenshot, when the content creators and content producers are updating the Welcome page, they want to view the possible layout templates first—how the page looks. Then they want to apply the layout template, for example 1-2-1 columns. For more details, populate the book_reports (Reports for Books) portlet in column-1; populate the jsp_portlet (JSP Portlet) portlet in column-2; and populate the Web Content Display (with portlet ID 56) portlet in column-3 and column-4.

Liferay Portal 5.2 Systems Development

Setting up pages, layout templates, and portlets mappings

First of all, we need to set up mappings among pages, templates, and portlets. Normally, we can specify these mappings in portal-ext.properties. Let's add the following lines at the end of portal-ext.properties:

## Portlets for layouts
Guest_Welcome_1_2_columns_i=book_reports,jsp_portlet,56
Guest_Welcome_1_2_columns_ii=56,56,56
Guest_Welcome_1_2_1_columns=book_reports,jsp_portlet,56,56
Guest_Welcome_2_2_columns=56,56,56,56
Guest_Ext_1_2_1_columns=56,56,56,56
Guest_Ext_2_2_columns=56,56,book_reports, jsp_portlet

As shown in the code above, it specifies the mappings among community, pages, layout templates, and portlets. For the Welcome page and the children pages of the Guest community, four layout templates are available: 1_2_columns_i, 1_2_columns_ii, 1_2_1_columns, and 2_2_columns. For example, the Guest_Welcome_1_2_1_columns key contains four portlets: book_reports, jsp_portlet, and two Web Content Display portlets.

The layout template 1_2_1_columns is reused by at least two pages: Welcome and Ext. Further, the 1_2_1_columns layout can be applied flexibly for different pages with different portlets associated. Most importantly, you can configure the mappings among the community, pages, layout templates, and portlets. Obviously, you can also use customized layout templates with associated customized portlets.

Adding layout templates

Now we need to add an action in order to add the layout templates for pages. To do so, first add the following lines before the line String redirect = ParamUtil.getString(actionRequest, "pagesRedirect"); in ExtEditPagesAction.java under the com.ext.communities.action package:

else if (cmd.equals("template")) { addTemplate(actionRequest); }

Then add the following method before the last } in ExtEditPagesAction.java:

protected String addTemplate(ActionRequest actionRequest) throws Exception {
String prefixColumn = "column-";
String layoutTemplateId = ParamUtil.getString(actionRequest,
"layoutTemplateId");
String groupSectionName = ParamUtil.getString(actionRequest,
"groupSectionName");
String redirect = "";
ThemeDisplay themeDisplay = (ThemeDisplay) actionRequest.
getAttribute(WebKeys.THEME_DISPLAY);
long userId = themeDisplay.getUserId();
long groupId = themeDisplay.getScopeGroupId();
boolean privateLayout = ParamUtil.getBoolean(actionRequest, "
privateLayout");
long layoutId = ParamUtil.getLong(actionRequest, "layoutId");
Layout layout = LayoutLocalServiceUtil.getLayout(groupId,
privateLayout, layoutId);
LayoutTypePortlet layoutTypePortlet = (LayoutTypePortlet)
layout.getLayoutType();
layoutTypePortlet.setLayoutTemplateId(userId, layoutTemplateId);
layoutTypePortlet.resetStates();
LayoutServiceUtil.updateLayout(layout.getGroupId(),
layout.isPrivateLayout(), layout.getLayoutId(),
layout.getTypeSettings());
redirect = PortalUtil.getLayoutURL(layout, themeDisplay);
String plIds[] = PropsUtil.getArray(groupSectionName +
layoutTemplateId);
List<String> list = layoutTypePortlet.getPortletIds();
for( int i=0; i< list.size(); i++ ){
String obj = (String) list.get(i);
PortletPreferencesLocalServiceUtil.deletePortletPreferences
(0, 3, layout.getPlid(), obj);
layoutTypePortlet.removePortletId(userId, obj);
}
if(plIds != null) { layoutTypePortlet.resetStates();
for(int i=0;i < plIds.length; i++){
layoutTypePortlet.addPortletId(userId, plIds[i], prefixColumn +
(i+1), 0);
}
LayoutServiceUtil.updateLayout(layout.getGroupId(),
layout.isPrivateLayout(), layout.getLayoutId(),
layout.getTypeSettings());
}
return redirect;
}

As shown in the code above, it first adds an action-handling command template. Then it gets page, layout template, and associated portlets. Finally, it populates the associated portlets within the selected layout for a given page.

Displaying layout templates by sections

We have added the mappings among community, pages, layout templates, and portlets. We have also added an action to handle the layout template updates. Now let's update JSP files in order to display and apply the layout templates by sections — first-level pages from root, for example, the community name Guest.

First, let's update the JSP file edit_pages_public_and_private.jspf in order to include possible layout templates instead of printing a static message. To do so, simply replace the line tabs3Names = <%= tabs3Names %> with the following line:

<liferay-util:include page="/html/portlet/ext/communities/
edit_pages_layout_templates.jsp" />

Then, let's create a JSP file edit_pages_layout_templates.jsp as follows:

  1. Create a JSP file edit_pages_layout_templates.jsp in the /ext/ext-web/docroot/html/portlet/ext/communities folder and open it.
  2. Add the following lines at the beginning of edit_pages_layout_templates.jsp and save it:
      <%@ include file="/html/portlet/ext/communities/init.jsp" %> 
      <% String redirect = ParamUtil.getString(request, "redirect");
      Layout selLayout = (Layout)request.getAttribute("edit_pages.jsp-
      selLayout");
      %>
      <c:if test="<%= themeDisplay.isSignedIn() && (selLayout != null)
      && selLayout.getType().equals(LayoutConstants.TYPE_PORTLET) %>">
      <input name="doAsUserId" type="hidden"
      value="<%= themeDisplay.getDoAsUserId() %>" />
      <input name="<%= Constants.CMD %>" type="hidden"
      value="template" />
      <input name="<%= WebKeys.REFERER %>" type="hidden"
      value="<%= HtmlUtil.escape(redirect) %>" />
      <input name="refresh" type="hidden" value="true" />
      <table border="0" cellpadding="0"
      cellspacing="10" style="margin-top: 10px;" width="100%">
      <% int CELLS_PER_ROW = 4; List layoutTemplates =
      LayoutTemplateLocalServiceUtil.
      getLayoutTemplates(theme.getThemeId());
      layoutTemplates = PluginUtil.restrictPlugins
      (layoutTemplates, user);
      LayoutTypePortlet selLayoutTypePortlet = (LayoutTypePortlet)
      selLayout.getLayoutType();
      Group group = selLayout.getGroup();
      String groupSectionName = group.getName()+ "_" +
      selLayout.getName(locale)+"_";
      if(selLayout.getParentLayoutId() != LayoutConstants.
      DEFAULT_PARENT_LAYOUT_ID){
      List parents = selLayout.getAncestors();
      String parentName = ((Layout)parents.get(parents.size()-
      1)).getName(locale);
      groupSectionName = group.getName()+ "_" + parentName +"_";
      }
      %>
      <input name="groupSectionName" type="hidden"
      value="<%= groupSectionName %>" />
      <%
      int index = 0;
      for (int i = 0; i < layoutTemplates.size(); i++) {
      LayoutTemplate layoutTemplate = (LayoutTemplate)
      layoutTemplates.get(i);
      String key = PropsUtil.get(groupSectionName +
      layoutTemplate.getLayoutTemplateId());
      if(key != null){
      %>
      <c:if test="<%= (index % CELLS_PER_ROW) == 0 %>">
      <tr></c:if>
      <td align="center" width="<%= 100 / CELLS_PER_ROW %>%">
      <img onclick="document.getElementById('layoutTemplateId
      <%= i %>').checked = true;"
      src='//dgdsbygo8mp3h.cloudfront.net/sites/default/files/blank.gif' data-original="<%= layoutTemplate.getContextPath() %>
      <%= layoutTemplate.getThumbnailPath() %>" /><br />
      <input <%= selLayoutTypePortlet.getLayoutTemplateId().
      equals(layoutTemplate.getLayoutTemplateId()) ? "checked" :
      "" %> id="layoutTemplateId<%= i %>"
      name="layoutTemplateId" type="radio"
      value="<%= layoutTemplate.getLayoutTemplateId() %>" />
      <label for="layoutTemplateId<%= i %>">
      <%= layoutTemplate.getName() %>
      </label>
      </td>
      <c:if test="<%= (index % CELLS_PER_ROW) == (CELLS_PER_ROW - 1)
      %>"> </tr></c:if> <% index++; } } %>
      </table>
      <input class="form-button" type="submit"
      value="<liferay-ui:message key="apply" />"
      style="margin: 10px" />
      </c:if>

As shown in the code above, it uses the first-level navigations as sections. The children pages of a section will share the same group of layout templates.

In short, a layout is an instance of a single page, which is composed of one or more portlets arranged inside various columns. Layout templates define the ways in which portlets will be arranged on a page. You, as a developer, can group the layout templates flexibly and, further, dynamically apply the layout templates for layout pages.

Tracking pages

We have built a lot of pages as well. Suppose we want to track all pages using Google Analytics (GA), for example, in order to show how to extend Liferay portal's out of the box tracking ability. Configuring Liferay portal to work with Google Analytics is pretty simple. The following are the main steps to set up Google Analytics:

Google Analytics generates detailed statistics about the visitors to a web site. Refer to http://www.google.com/analytics.

Then, let's customize the bottom-ext.jsp file in the /ext/ext-web folder as follows:

  1. Create a /common/themes folder page in the /ext/ext-web/docroot/html folder.
  2. Create a JSP file bottom-ext.jsp in the /ext/ext-web/docroot/html/common/themes folder and open it.
  3. Add the following lines at the end of this file and save it:
      <script type="text/javascript">
      var gaJsHost = (("https:" == document.location.protocol) ?
      "https://ssl." : "http://www.");
      document.write(unescape("%3Cscript src='//dgdsbygo8mp3h.cloudfront.net/sites/default/files/blank.gif' data-original='" + gaJsHost + "google-
      analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
      </script>
      <script type="text/javascript">
      var pageTracker = _gat._getTracker("UA-5808951-1");
      pageTracker._trackPageview();
      </script>

As shown in the code above, it uses a single Google Analytics account UA-5808951-1 to track the entire portal.

Using communities and layout page efficiently

We have discussed how to customize and extend the community and layout pages. Each community has a set of pages, either public or private. You can assign users, roles, permissions, and user groups for a given community. Here we will discuss how to use the community and layout pages efficiently.

Liferay portal extends the security model by resources, users, organizations, locations, user groups, and communities, roles, permissions, and so on. Liferay portal provides a fine-grained permission security model, which is a full-access control security model. At the same time, Liferay also provides a set of administrative tools that we have discussed above to configure and control the membership.

Employing group, community, and permissions

As shown in the following figure, a resource is a base object and permission is an action on a resource. A role is a collection of permissions. A user is an individual. Depending on what permissions and roles have been assigned, the user either does or does not have the permission to perform certain tasks.

Organizations represent the enterprise and departments hierarchy. Organizations can contain other organizations. Moreover, an organization acting as a child organization of a top-level organization can also represent departments of a parent corporation:

Liferay Portal 5.2 Systems Development

A Location is a special organization with one, and only one, associated parent organization and without an associated child organization. Organizations can have any number of locations and suborganizations. Both roles and individual permissions can be assigned to organizations (locations or suborganizations). By default, locations and suborganizations inherit permissions from their parent organization.

A Community is a special group. It may hold a number of users who share common interests. Both roles and individual permissions can be assigned to communities.

Finally, a user group is a special group with no context, which may hold a number of users. Both roles and individual permissions can be assigned to user groups, and every user who belongs to that user group will receive the role or permission.

Using communities, layout pages, comments, and ratings

As shown in the following figure, a community is made up of a set of pages, including private pages and public pages. You can use a community (for example Book Street) to represent a web site (for example www.bookpubstreet.com), where the public pages represent the public site for public end users in the frontend, and the private pages are employed to present web content management for content creators, content publishers, and content editors in the backend.

A layout page consists of a couple of portlets, including the Journal Content portlet. More interestingly, a layout page may have page comments and associated page ratings. You can specify the comments and ratings in the journal articles.

Liferay Portal 5.2 Systems Development

Extending the community and layout pages

We have customized and extended the communities and layout pages in the Ext. At the same time, we did not add columns to Liferay Group_ table and Layout table. As shown in the preceding figure, we have just created additional tables (for example ExtGroup and ExtLayout) with a 1:1 relationship with the Group_ table and Layout table, respectively. With this, we will prevent the upgrade risk properly and make the extension reusable.

Users can belong to any number of communities and inherit permissions and roles from them. Notice that in the Group_ table, there is class-Name and class-PK column. If these columns are blank, then the record is a normal community. If class-Name is com.liferay.portal.model.User, then the record represents a private user community. This is used only for Power Users. If the class-Name is com.liferay.portal.model.Organization, then the record represents an organization or location. If the class-Name is com.liferay.portal.model.UserGroup, then the record represents a user group. For instance, if both class-Name and class-PK columns are blank in Group_, it means that this is a normal community, for example Book Street.

Summary

This article introduced how to customize page management with more features such as adding localized features, adding tags, employing layout templates dynamically, tracking pages, and so on. It also showed us how to use the Communities and Layout Pages efficiently.


If you have read this article you may be interested to view :


Liferay Portal 5.2 Systems Development Liferay Portal 5.2 Systems Development
Published: May 2009
eBook Price: $32.99
Book Price: $54.99
See more
Select your format and quantity:

About the Author :


Jonas X. Yuan

Jonas X. Yuan is a Chief Architect of ForgeLife LLC and an expert on Liferay Portal, e-commerce, and Content Management Systems (CMS). As an open source community contributor, he has published five Liferay books from 2008 to 2012. He is also an expert on Liferay integration with Ad Server OpenX, different search engines, enterprise content including videos, audio, images, documents, and web contents, and other technologies, such as BPM Intalio and Business Intelligence Pentaho, LDAP, and SSO. He holds a Ph.D. in Computer Science from the University of Zurich, where he focused on Integrity Control in federated database systems.

He earned his M.S. and B.S. degrees from China, where he conducted research on expert systems for predicting landslides. Previously, he worked as a Project Manager and a Technical Architect in Web GIS (Geographic Information System).
He is experienced in Systems Development Lifecycle (SDLC) and has deep, hands-on skills in J2EE technologies. He developed a BPEL (Business Process Execution Language) engine called BPELPower from scratch at the NASA data center. As the chief architect, Dr. Yuan successfully led and launched several large-scale Liferay/Alfresco e-commerce projects for millions of users each month.

He has worked on the following books: Liferay Portal Enterprise Intranets, 2008; Liferay Portal 5.2 Systems Development, 2009; Liferay Portal 6 Enterprise Intranets, 2010; Liferay User Interface Development, 2010; Liferay Portal Systems Development, 2012.

Books From Packt


Apache Maven 2 Effective Implementations: RAW
Apache Maven 2 Effective Implementations: RAW

Pentaho Reporting 1.0 for Java Developers
Pentaho Reporting 1.0 for Java Developers

Drools JBoss Rules 5.0 Developer's Guide
Drools JBoss Rules 5.0 Developer's Guide

Grails 1.1 Web Application Development
Grails 1.1 Web Application Development

Seam 2.x Web Development
Seam 2.x Web Development

JBoss Drools Business Rules
JBoss Drools Business Rules

JBoss Tools 3 Developers Guide
JBoss Tools 3 Developers Guide

Spring Web Flow 2 Web Development
Spring Web Flow 2 Web Development


Your rating: None Average: 4.5 (2 votes)

Post new comment

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
K
T
H
1
R
c
Enter the code without spaces and pay attention to upper/lower case.
Code Download and Errata
Packt Anytime, Anywhere
Register Books
Print Upgrades
eBook Downloads
Video Support
Contact Us
Awards Voting Nominations Previous Winners
Judges Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software
Resources
Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software