6.0.0.2
Copyright © 2010-2011 portletfaces.org
Legal Notice
Copyright © 2010-2011 by portletfaces.org. This copyrighted material is made available to anyone wishing to use, modify, copy, or redistribute it subject to the terms and conditions of the Apache License, Version 2.0.
The LiferayFaces project is designed to make it easier to develop JSF 2 portlets that run within Liferay Portal. The project home page can be found at http://www.portletfaces.org/projects/liferayfaces. LiferayFaces contains a wealth of features that expose the standard features of the Portlet 2.0 API and vendor-specific features of Liferay in a way that is natural to JSF development. The following is a list of high level features:
Note that the LiferayFaces project is the successor to the PortletFaces-Tools project for JSF 1.2.
JSF web application developers typically call FacesContext.getCurrentInstance() in order to obtain the ThreadLocal
singleton instance associated with the current request. While JSF portlet developers can certainly do the
same, it's easier to call LiferayFacesContext.getInstance() which returns an application-scoped singleton instance.
Example 1.1. Obtaining the LiferayFacesContext Singleton Instance
public class SessionScopedManagedBean {
private final LiferayFacesContext liferayFacesContext = LiferayFacesContext.getInstance();
public List<DlFileEntry> getDocuments() {
List<DLFileEntry> documents;
try {
documents = DLFileEntryLocalServiceUtil.getFileEntries(folderId);
}
catch (Exception e) {
logger.error(e.getMessage(), e);
// Don't have to call LiferayFacesContext.getInstance() first since
// a reference to it was obtained when the bean was created.
liferayFacesContext.addGlobalUnexpectedErrorMessage();
}
return documents;
}
}
LiferayFacesContext is an abstract class that extends the JSF FacesContext abstract class. Because of thism it supplies all the same method signatures and can therefore do anything that FacesContext can do. The LiferayFacesContext implements the delegation design pattern for methods defined by FacesContext by first calling FacesContext.getCurrentInstance() and then delegating to corresponding methods. The benefit of using this technique is that JSF portlet developers only have to call LiferayFacesContext.getInstance() once, and can save the singleton object reference for future use.
LiferayFaces introduces several variables into the Expression Language (EL).
Table 1.1. LiferayFaces EL Variables
| EL Variable | Description |
|---|---|
i18n
|
As an abbreviation for the word "internationalization", the i18n EL
variable enables page authors to declaratively specify message keys that hook into Liferay's
Language Utility.
Type:
|
liferay
|
Utility managed-bean that is designed to be kept in JSF request scope.
Its purpose is to introduce some Liferay-specific variables into the JSF
EL.
Type:
|
liferay.companyId
|
The Liferay companyId primary key value associated with the community/organization portal
page that the current portlet is placed upon.
Type:
|
liferay.documentLibraryURL
|
The absolute URL for the Liferay Document Library Struts action
path.
Type:
|
liferay.imageGalleryURL
|
The absolute URL for the Liferay Image Gallery Struts action
path.
Type:
|
liferay.imageURL
|
The absolute URL for the Liferay Image Servlet.
Type:
|
liferay.groupUser
|
The Liferay User that owns the Liferay community/organization portal
page that the current portlet is placed upon.
Type:
|
liferay.layout
|
The Liferay Layout associated with the community/organization portal
page that the current portlet is placed upon.
Type:
|
liferay.permissionChecker
|
The Liferay PermissionChecker associated with the current request and
Liferay User.
Type:
|
liferay.portalURL
|
The absolute URL for the portal.
Type:
|
liferay.portlet
|
the containing Liferay Portlet associated with the
PortletRequest.
Type:
|
liferay.portraitURL
|
Designed to be called from the EL by passing a Liferay User or
userId as an array index, returns the absolute URL to the user's
portrait.
Type:
|
liferay.theme
|
The Liferay Theme associated with the Liferay
Layout.
Type:
|
liferay.themeDisplay
|
The Liferay ThemeDisplay associated with the
PortletRequest.
Type:
|
liferay.themeImageURL
|
Designed to be called from the EL by passing a relative path to a theme image as an array
index, returns the absolute URL to the theme image.
Type:
|
liferay.themeImagesURL
|
The absolute URL for the image path associated with the current Liferay
Theme.
Type:
|
liferay.user
|
The Liferay User associated with the
PortletRequest.
Type:
|
liferay.userHasPortletPermission
|
Designed to be called from the EL by passing an action-key as an array
index, returns a Boolean indicating whether or not the Liferay
User associated with the PortletRequest has permission to
execute the specified action-key on the current
portlet.
Type:
|
As an abbreviation for the word "internationalization", the i18n
EL variable enables page authors to declaratively specify message keys that are provided by one of the
following:
The Liferay Language Utility is typically accessed by portlet developers by calling static Java
methods found in the LanguageUtil class. The utility operates by reading the
locale-specific version of the portal's Language.properties file, which contains thousands of keys and
internationalized messages.
Portlet developers can extend the Liferay Language Utility by creating a file within the portlet WAR
named WEB-INF/liferay-hook.xml that points to locale-specific resource bundles
that are in the runtime classpath of the portlet.
Example 1.2. WEB-INF/liferay-hook.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hook PUBLIC "-//Liferay//DTD Hook 6.0.0//EN" "http://www.liferay.com/dtd/liferay-hook_6_0_0.dtd"> <hook> <language-properties>Language_en_US.properties</language-properties> </hook>
Example 1.3. Contents of Language_en_US.properties
add-new-entry=Add New Entry save-entry=Save Entry
When using JBoss EL, page authors can take advantage of the i18n.replace() method
in order to substitute values into the text of the message.
Example 1.5. Usage of the i18n EL Variable with JBoss EL
<!--
Note: The US English translation of the x-has-x-friends key would look like the following:
x-has-x-friends={0} has {1} friends.
-->
<h:outputText value="#{i18n.replace('x-has-x-friends', liferay.groupUser.fullName, friendsModel.dataModel.rowCount)}" />
This is a utility managed-bean that is designed to be kept in request scope. Its purpose is to introduce some Liferay-specific variables into the JSF EL. The reason why this is implemented as a managed-bean (and not as an ELResolver) is because it needs to kept in JSF 2 ViewScope.
The Liferay companyId primary key value associated with the community/organization portal page that the current portlet is placed upon.
Example 1.6. EL Usage of liferay.companyId
<h:outputText value="#{liferay.companyId} is the companyId associated with this set of Liferay Portal pages." />
The absolute URL for the Liferay Document Library Struts action path prefix. The most common use case is to append the /get_file suffix and some additional request parameters in order to provide a hyperlink to a document in the Liferay Document Library. See the Liferay struts-config.xml file for a complete list of available suffixes.
Example 1.7. EL Usage of liferay.documentLibraryURL
<h:dataTable id="documents" value="#{documentModelBean.dataModel}" var="dlFileEntry">
<h:column>
<f:facet name="head">
<h:outputText value="#{i18n['file-name']}" />
</f:facet>
<h:outputLink
target="_blank"
value="#{liferay.documentLibraryURL}/get_file?p_l_id=#{liferay.themeDisplay.plid}&folderId=#{dlFileEntry.folderId}&name=#{dlFileEntry.name}">
<h:outputText value="#{dlFileEntry.title}" />
</h:outputLink>
</h:column>
</h:dataTable>
The Liferay User that owns the Liferay community/organization portal page that the
current portlet is placed upon.
Example 1.8. EL Usage of liferay.groupUser
<h:outputText
value="The user named #{liferay.groupUser.fullName} owns this set of Liferay Portal pages." />
The absolute URL for the Liferay Image Gallery Struts action path prefix. See the Liferay struts-config.xml file for a complete list of available suffixes.
The absolute URL for the Liferay Image Servlet. Although this can be used to construct a URL that
points a Liferay user's portrait/photo, for performance reasons, it is better to use the portraitURL EL variable instead.
The Liferay Layout associated with the community/organization portal page that the
current portlet is placed upon.
Example 1.9. EL Usage of liferay.layout
<h:outputText
value="The name of this portal page is #{liferay.layout.name}" />
The Liferay PermissionChecker associated with the current request and Liferay
User.
Example 1.10. EL Usage of liferay.permissionChecker
<h:commandButton actionListener="#{backingBean.save}" rendered="#{liferay.permissionChecker.companyAdmin}" value="#{i18n['save']}" />
The containing Liferay Portlet associated with the
PortletRequest.
Example 1.11. EL Usage of liferay.portlet
<h:outputText
value="The name of this portlet is #{liferay.portlet.displayName}" />
Designed to be called from the EL by passing a Liferay User or
userId as an array index, returns the absolute URL to the user's portrait.
Example 1.12. EL Usage of liferay.portraitURL
<h:graphicImage value="#{liferay.portraitURL[liferay.group.user]}" />
The Liferay Theme associated with the Liferay Layout.
Example 1.13. EL Usage of liferay.theme
<h:outputText value="The name of the Liferay theme applied to this portal page is #{liferay.theme.name}" />
The Liferay ThemeDisplay associated with the PortletRequest.
Perhaps it is easier to think of the Liferay ThemeDisplay as a "display context" which provides access
to a wealth of information including the current Company, User, Layout, Theme, PermissionChecker, and
more.
Example 1.14. EL Usage of liferay.themeDisplay
<link href="#{liferay.themeDisplay.uRLSignIn}">#{i18n['sign-in']}</link>
Designed to be called from the EL by passing a relative path to a theme image as an array index, returns the absolute URL to the theme image.
Example 1.15. EL Usage of liferay.themeImageURL
<h:graphicImage value="#{liferay.themeImageURL['/common/delete.png']}" />
Returns the absolute URL for the image path associated with the current Liferay Theme. For example: http://localhost:8080/image/image_gallery.
Example 1.16. EL Usage of liferay.themeImagesURL
<h:graphicImage value="#{liferay.themeImagesURL}/common/delete.png" />
the Liferay User associated with the PortletRequest.
Example 1.17. EL Usage of liferay.user
<h:outputText value="#{i18n['welcome']}, #{liferay.user.firstName}" />
Designed to be called from the EL by passing an action-key as an array index, returns a
Boolean indicating whether or not the Liferay User associated with the
PortletRequest has permission to execute the specified action-key on the
current portlet. The action-key is typically defined in a Liferay
resource-action-mapping XML file that defines the
<portlet-resource/> and <model-resource/>
permissions associated with a Liferay portlet. Please refer to the
portal-impl/classes/resource-actions/messageboards.xml file in the Liferay Portal source code
distribution for an example of how to write a Liferay resource-action-mapping XML
file.
Example 1.18. EL Usage of liferay.userHasPortletPermission
<h:dataTable
rendered="#{liferay.userHasPortletPermission['VIEW']}"
value="#{modelManagedBean.users}"
var="user">
</h:dataTable>
LiferayFaces provides the following UIComponent tags as part of its component suite.
Table 1.2. UIComponent Tags
| Tag | Description |
|---|---|
liferay-ui:input-editor
|
Renders a text area that provides the ability to enter rich text such as bold, italic, and underline. |
liferay-security:permissionsURL
|
Renders an HTML anchor tag (hyperlink) that the user can click on in order to see the Liferay Permissions screen for the associated resource. |
The liferay-ui:input-editor tag renders a text area that provides the ability to enter
rich text such as bold, italic, and underline. The renderer relies on the CKEditorTM to provide the rich
text editing area. Since Liferay bundles the CKEditorTM JavaScript and related images with the portal, the
portlet developer does not need to include it with the portlet.
Prior to Liferay 6.0 SP2 (6.0.12), the rich text area was rendered as an <iframe>. But due to incompatibilities with IE, the rich text area HTML markup is now rendered "inline" with the portal page. LiferayFaces will automatically detect the version of Liferay and will render the rich text area accordingly. However, if you using Liferay 6.0 (6.0.10) or Liferay 6.0 SP1 (6.0.11) and have received an "inline" patch from Liferay Support, then you will need to add the following to the portlet's WEB-INF/web.xml descriptor:
<context-param>
<param-name>org.portletfaces.liferay.faces.inlineInputEditor</param-name>
<param-value>true</param-value>
</context-param>
Also, if the editor is "inline" and you are using a Servlet 2.5 container such as Tomcat 6, then it is necessary to add the following markup to the portlet's WEB-INF/web.xml deployment descriptor:
<listener>
<listener-class>org.portletfaces.liferay.faces.listener.StartupListener</listener-class>
</listener>
If using ICEfaces, then the "inline" version of liferay-ui:input-editor will expose an inefficiency in the Direct2DOMTM (DOM-diff) algorithm. Typing a single character in the rich text area will cause ICEfaces to detect a DOM-diff, causing the entire liferay-ui:input-editor to be replaced in the browser's DOM with the form is submitted via Ajax. The workaround for this problem is to use the JSF2 f:ajax component to optimize/control which parts of the JSF component tree are DOM-diffed by ICEfaces. For example:
<h:panelGroup id="feedback">
<h:messages globalOnly="true" layout="table" />
</h:panelGroup>
<h:panelGroup id="editor">
<liferay-ui:input-editor value="#{modelBean.text}" />
</h:panelGroup>
<h:commandButton>
<f:ajax execute="@form" render="feedback" />
</h:commandButton>
Table 1.3. Attributes
| Attribute | Type | Description | Required |
|---|---|---|---|
| id | String | The identifier of the component | false |
| rendered | Boolean | Boolean flag indicating whether or not this component is to be rendered during the RENDER_RESPONSE phase of the JSF lifecycle. The default value is “true”. | false |
| value | String | The value of the component, the HTML fragment generated by the end-user. | true |
Example 1.19. Example usage of liferay-ui:input-editor tag
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<f:view xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:pf="http://portletfaces.org/facelets">
<h:form>
<liferay-ui:input-editor id="comments" value="#{modelManagedBean.comments}" />
</h:form>
</f:view>
The liferay-security:permissionsURL tag renders an HTML anchor tag (hyperlink) that the user can
click on in order to see the Liferay Permissions screen for the associated resource.
Table 1.4. Attributes
| Attribute | Type | Description | Required |
|---|---|---|---|
| id | String | The identifier of the component | false |
| modelResource | String | The fully qualified Java class of the model resource. For example:
MyModelResource.class.getName()
|
true |
| modelResourceDescription | String | The description of the model resource. | false |
| redirect | Boolean | The redirect URL. | false |
| rendered | Boolean | Boolean flag indicating whether or not this component is to be rendered during the RENDER_RESPONSE phase of the JSF lifecycle. The default value is “true”. | false |
| resourcePrimKey | String | The primary key value of the model resource. | false |
| value | String | The text of the hyperlink that the user will see and click on. | false |
Example 1.20. Example usage of liferay-security:permissionsURL tag
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<f:view xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:pf="http://portletfaces.org/facelets">
<h:form>
<liferay-security:permissionsURL
modelResource="org.portletfaces.myproject.model.Book"
modelResourceDescription="Book"
resourcePrimKey="#{modelManagedBean.book.bookId} />
</h:form>
</f:view>
LiferayFaces provides the following Facelet Composite Component tags as part of its component suite.
Table 1.5. Facelet Composite Component Tags
| Tag | Description |
|---|---|
liferay-ui:ice-info-data-paginator
|
Encapsulates an ICEfaces ice:dataPaginator tag that renders pagination information for an associated ice:dataTable. The navigation information will match the internationalized Liferay "showing-x-x-of-x-results" message. |
liferay-ui:ice-nav-data-paginator
|
Encapsulates an ICEfaces ice:dataPaginator tag that renders navigation controls for an associated ice:dataTable. The icons will match the current Liferay theme. |
liferay-ui:icon
|
Encapsulates an HTML img tag whose src attribute contains a
fully qualified URL to an icon in the Liferay theme.
|
The liferay-ui:ice-info-data-paginator encapsulates an ICEfaces ice:dataPaginator
tag that renders pagination information for an associated ice:dataTable. The
navigation information will match the internationalized Liferay "showing-x-x-of-x-results"
message.
Table 1.6. Attributes
| Attribute | Type | Description | Required |
|---|---|---|---|
| for | String | Corresponds to the value of an id attribute for an ice:dataTable tag.
|
true |
| value | String | Specifies a string that contains replacement tokens for each piece of pagination information. The default value is the internationalized Liferay "showing-x-x-of-x-results" message. | true |
Example 1.21. Example usage of liferay-ui:ice-info-data-paginator tag
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<f:view xmlns:f="http://java.sun.com/jsf/core"
xmlns:ice="http://www.icesoft.com/icefaces/component"
xmlns:pf="http://portletfaces.org/facelets">
<liferay-ui:ice-info-data-paginator for="dataTable1" />
<ice:dataTable id="dataTable1" value="#{modelManagedBean.rows}" var="row">
...
</ice:dataTable>
</f:view>
The liferay-ui:ice-info-data-paginator encapsulates an ICEfaces ice:dataPaginator
tag that renders navigation controls for an associated ice:dataTable. The
icons will match the current Liferay theme.
Table 1.7. Attributes
| Attribute | Type | Description | Required |
|---|---|---|---|
| fastForwardIconRendered | Boolean | Boolean flag indicating whether or not the "Fast Forward" button/icon is rendered. The default value is "false". | false |
| fastRewindIconRendered | Boolean | Boolean flag indicating whether or not the "Fast Rewind" button/icon is rendered. The default value is "false". | false |
| firstIconRendered | Boolean | Boolean flag indicating whether or not the "First" button/icon is rendered. The default value is "true". | false |
| for | String | Corresponds to the value of an id attribute for an ice:dataTable tag.
|
true |
| lastIconRendered | Boolean | Boolean flag indicating whether or not the "Last" button/icon is rendered. The default value is "true". | false |
| nextIconRendered | Boolean | Boolean flag indicating whether or not the "Next" button/icon is rendered. The default value is "true". | false |
| paginator | Boolean | Boolean flag indicating whether or not the page number links will be rendered. This is a pass-through attribute for the encapsulated ice:dataPaginator. The default value is "true". | false |
| paginatorMaxPages | Integer | The maximum amount of pages to be displayed in the paginator. This is a pass-through attribute for the encapsulated ice:dataPaginator. The default value is 7. | false |
| previousIconRendered | Boolean | Boolean flag indicating whether or not the "Previous" button/icon is rendered. The default value is "true". | false |
Example 1.22. Example usage of liferay-ui:ice-nav-data-paginator tag
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<f:view xmlns:f="http://java.sun.com/jsf/core"
xmlns:ice="http://www.icesoft.com/icefaces/component"
xmlns:pf="http://portletfaces.org/facelets">
<liferay-ui:ice-nav-data-paginator for="dataTable1" />
<ice:dataTable id="dataTable1" value="#{modelManagedBean.rows}" var="row">
...
</ice:dataTable>
</f:view>
The liferay-ui:icon tag encapsulates an HTML img tag whose src
attribute contains a fully qualified URL to an icon image in the current Liferay theme.
Table 1.8. Attributes
| Attribute | Type | Description | Required |
|---|---|---|---|
| alt | String | Corresponds to the value of the alt attribute for the embedded
img tag. The default value is Liferay's internationalized message
for the key named view.
|
false |
| image | String | The name of the theme image icon, which can be the prefix of any image filename in
the Liferay theme's "common" image folder. The default value is
view.
|
false |
Example 1.23. Example usage of liferay-ui:icon tag
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<f:view xmlns:f="http://java.sun.com/jsf/core"
xmlns:ice="http://www.icesoft.com/icefaces/component"
xmlns:pf="http://portletfaces.org/facelets">
<liferay-ui:icon alt="#{i18n['delete']}" image="delete" />
</f:view>
LiferayFaces offers several features that help integrate JSF portlets with the current Liferay theme.
LiferayFaces provides the LiferayFacesContext.getThemeDisplay() method at the Java level and also the liferay.themeDisplay EL variable for getting access to the Liferay ThemeDisplay object.
LiferayFaces provides the liferay-ui:icon Facelet composite component tag
that encapsulates an HTML img tag whose src attribute contains a fully
qualified URL to an icon image in the current Liferay theme. Additionally, LiferayFaces provides the
liferay.themeImagesURL and liferay.themeImageURL Facelet composite component tags
for gaining access to theme image icons.
Most of the standard JSF HTML component tags render themselves as HTML markup such as
<label />, <input />, <span
/>, etc. and assume the current Liferay theme thanks to the power of CSS. However, the
h:messages and h:message tag will not assume the current Liferay theme unless the following JSR 286
standard CSS class names are applied:
portlet-msg-error
portlet-msg-info
portlet-msg-warn
Example 1.24. JSR 286 standard CSS class names applied to the h:messages tag
<h:messages errorClass="portlet-msg-error" fatalClass="portlet-msg-error" infoClass="portlet-msg-info" warnClass="portlet-msg-warn" />
As a convenience, LiferayFaces provides the liferay-ui:messages and liferay-ui:message Facelet composite component tags that encapsulate the h:messages and h:message tags respectively, and automatically apply the JSR 286 standard class names as shown above.
When running as a portlet, the ICEfaces ice:messages and ice:message component tags automatically apply the JSR 286 standard class names as shown above. Additionally the ice:dataTable component tag will apply the following JSR 286 standard class names for alternating table rows:
portlet-section-alternate
portlet-section-body
In a normal JSF web application, the Locale that is used
to display internationalized values is dictated by the locale specified in the end-user's web-browser.
However, Liferay Portal permits the user to select a different locale (language) using the Language Portlet.
The user's choice is ultimately saved as a languageId in the Liferay User object and is persisted to the database.
In order to provide seamless integration between JSF portlets and the language selected by the user,
LiferayFaces provides the LiferayLocalePhaseListener. The listener monitors the RESTORE_VIEW phase of the JSF lifecycle
and will automatically set the locale inside the UIViewRoot according to the value specified by Liferay's User.getLocale() method, which is aware of the selected languageId. This in
turn causes internationalization techniques such as the f:loadBundle tag and the i18n EL keyword to
automatically translate message keys into the language selected by the user with the Liferay Language
Portlet.