Minimizing the ext environment

Company Blogs 19. Februar 2010 Von Amos Fong Staff

There has been a lot of work trying to minimize the use of the ext environment to keep your site more maintainable and easier to customize. Here are some tips that has helped me keep my ext small and more maintainable/manageable which will also make upgrades more smooth.


Move anything possible in ext to hooks.

1. Do you need to override a * class? (v6.0 or later)

For example, to override the UserLocalServiceImp class put this in your liferay-hook.xml


Then in your class just extend the UserLocalServiceWrapper and override any methods you want.

public class TestUserLocalServiceImpl extends UserLocalServiceWrapper {

Check out the test-hook portlet located in svn:// for more info.


2. Do you need to override any classes listed in the liferay-hook.dtd or do you need to add event actions?

For example, do you need to override the ScreennameValidator, ScreennameGenerator, Document library hook, or add postLoginActions, servicePreActions, etc.? These can be overriden through in a hook and even allow hot deploy overriding! That means you don't need to restart tomcat to test a new change, you can just redeploy your hook. See the full list in lifeary-hook_6_0_0.dtd. New properties will continually be added so keep an eye for new ways to minimize your ext.


Use custom attributes.

1. Do you need to customize user attributes?

Instead of modifying service.xml to add a new column and regenerating all the services, use a custom attribute. There is practically no performance difference, String attributes (only string!) are indexed, and you can do it through the admin GUI. One thing you need to keep in mind is to give view or update permissions apprpriately.

They are even picked up automatically in the create account form! You don't even need to modify any java classes to add a new attribute for registering. Just create a JSP hook and add this easy taglib to the create_account.jsp.

            classPK="<%= 0 %>"
            editable="<%= true %>"
            label="<%= true %>"

 In the action class, it will pick any custom attributes and update them accordingly. The same is true for most all other models too (ie Documents, Images, Web content).


Extend rather than override.

1. Do you need to override any * classes?

Any classes in struts-config.xml or liferay-portlet.xml should be extended rather than overrided. This will hopefully make upgrading less painfulby keeping the current code and just adding your own or tweaking variables so you get the behaviour you want.

For example, say you created a custom attribute "Favorite Color" and you want to make it required to be filled out.

        <action path="/login/create_account" type="com.liferay.test.ext.portlet.login.action.TestCreateAccountAction">
            <forward name="portlet.login.create_account" path="portlet.login.create_account" />

Then in your class:

public class TestCreateAccountAction extends CreateAccountAction {
    protected void addUser(ActionRequest actionRequest, ActionResponse actionResponse)
        throws Exception {

        Map<String, Serializable> expandoBridgeAttributes =
                ExpandoBridgeFactoryUtil.getExpandoBridge(User.class.getName()), actionRequest);

         String favoriteColor = (String)expandoBridgeAttributes.get("favoriteColor");

         if (Validator.isNull(favoriteColor)) {
                throw new RequiredFieldException("favoriteColor", "favoriteColorLabel"); // v6.0/EE specific code

        super.addUser(actionRequest, actionResponse);  // Don't touch current code to make upgrades painless =)


2. Do you need to override JSPs?

Use a JSP hook. (See

And use the buffer util taglib to achieve a similar affect to what I did with class above. Let's say we want to remove the javascript on the bottom, change the word "save" to "create" and add the custom attribute favorite color to the registration form after the last name.


<%@ include file="/html/portlet/login/init.jsp" %>

<liferay-util:buffer var="html">
    <liferay-util:include page="/html/portlet/login/create_account.portal.jsp" />

<liferay-util:buffer var="customHtml">
        classPK="<%= 0 %>"
        editable="<%= true %>"
        label="<%= true %>"

int x = html.lastIndexOf("<script type=\"text/javascript\"");

if (x != -1) {
    y = html.indexOf("</script>", x);

    html = html.substring(0, x) + html.substring(y + 9);

html = html.replace(LanguageUtil.get(pageContext, "save"), LanguageUtil.get(pageContext, "create"));

x = html.indexOf(LanguageUtil.get(pageContext, "last-name"));

if (x != -1) {
    y = html.indexOf("</div>", x);

    html = html.substring(0, y) + customHtml + html.substring(y);

<%= html %>



Hopefully that was useful to you. Of course, this isn't always possible and you'll have to resort to direct overwriting. But I hope this can minimize the pain of upgrading for some people.

If there are commonly overrided classes, let's see if we can figure out ways to make it easier, make it possible to use a technique mentioned above, or be moved to a hook =). Or...contribute to trunk if it's useful, that way we maintain it for you and others also benefit from it.

If you guys have any other methods you like to use or if I missed anything, please leave a comment.

Zeige 1 Ergebnisse.