How to use Custom Attributes to enhance Users
Howto use Custom Attributes automatically and programatically. #
Out-Of-The-Box Features #
Liferay provides a UI and API to allow for the creation of customized attributes associated with any entity generated by Service Builder. These attributes provide for extensibility without the need for extending the Liferay DB schema.
Out of the box Liferay provides Custom Attributes UI for Users and Organizations.
Creating Custom Attributes for Users #
- Login as an Administrator
- Navigate to the 'Control Panel' from the 'Dock'
- Select 'Custom Fields' from the left hand side navigation bar
- Select 'User'
- Click 'Add Custom Attribute'
- Specify the 'Key' for the Custom Attribute. The help icon for this field reads; "The custom attribute key is used to access the attribute programatically through the <liferay-ui:custom-attribute /> tag." More on this later.
- The Key must not contain spaces or special characters. Use
- underscores (my_key)
- dashes (my-key)
- or camel case (myKey)
- Specify the type of the attribute. The help icon for this field reads; "Choose the attribute type carefully as once it is defined it cannot be changed."
Note: Only "java.lang.String" type fields can be made searchable. Consider this at time of creation.
- Specify if the field is hidden. The help icon for this field reads: "Setting a custom attribute to hidden means that the attribute's value is never shown in any user interface besides this one. This allows the attribute to be used for some more obscure and advanced purposes such as acting as a placeholder for custom permissions." This setting can be changed at any time
- Click "Save"
Updating Custom Attribute settings #
- Once the attribute is saved, you are returned to the list. Click the new attribute's link to return to the edit view
- You will notice that the Name is automatically rendered based on a formatting of the 'key', but also note that this rendering does not grant automatic localization. In order to create true localization, define those in the Language.properties files based on the attribute's 'key'
- There is now an option to specify a default value
- If the attribute is of type 'java.lang.String', you have the option to make the custom attribute 'Searchable' (this only currently works for User as the underlying service must support integrated custom attribute indexing). The help icon for this field reads; "Setting a custom attribute to searchable means that the value of the attribute will be indexed when the entity (such as User) is modified. Only java.lang.String attributes can be made searchable. Note that when an attribute is newly made searchable, the indexes must be updated before the data is available to search."
- Click "Save"
Updating Custom Attribute permissions #
- Once the attribute is again saved, you are returned to the list. Click the 'Actions' button at the right end of the row for a given attribute
- Click 'Permissions'
- Assign the actions to the Roles as desired.
- Note if the field is 'hidden' the attribute is still only visible in this UI.
Viewing and setting Custom Attributes per User instance #
- Select any user from the user list or visit the My Account view
- Choose the 'Custom Attributes' link from the right hand side navigation bar
- Depending on permissions and settings you are presented with the current list of editable and/or not-editable attributes.
- If the field is editable, enter a value and click 'Save'
Using Custom Attribute tags to display editable or non-editable values #
Using the <liferay-ui:custom-attribute-list /> jsp tag #
- This tag generates a list of all the (non-hidden, and VIEWable) tags for a given entity type and instance
- The available parameters are:
- className, the fully qualified name of the entity (required = true) e.g. com.liferay.portal.model.User
- classPK, the primaryKey of the entity instance (or zero (0) if there is not currently an instance) (required = true)
- editable, is this invocation to check UPDATE permission and show as a input field if check returns true (required = false, default = false)
- label, is the label of the field rendered, if not simply show the raw output of the attribute value (required = false, default = false)
- A sample invocation looks like:
<liferay-ui:custom-attribute-list className="<%= User.class.getName() %>" classPK="<%= selUser != null ? selUser.getUserId() : 0 %>" editable="<%= true %>" />
Using the <liferay-ui:custom-attribute /> jsp tag #
- This tag generates a view of a specific attribute for a given entity type and instance.
- The available parameters are:
- className, the fully qualified name of the entity (required = true) e.g. com.liferay.portal.model.User
- classPK, the primaryKey of the entity instance (or zero (0) if there is not currently an instance) (required = true)
- editable, is this invocation to check UPDATE permission and show as a input field if check returns true (required = false, default = false)
- label, is the label of the field rendered, if not simply show the raw output of the attribute value (required = false, default = false)
- name, the name of the specific attribute to render (required = true)
- A sample invocation looks like:
<liferay-ui:custom-attribute className="<%= User.class.getName() %>" classPK="<%= selUser != null ? selUser.getUserId() : 0 %>" editable="<%= true %>" name="company-name" />
Performing a custom User search using specific custom attributes #
- The short method for performing an index search for Users is:
public Hits search( long companyId, String keywords, Boolean active, LinkedHashMap<String, Object> params, int start, int end, Sort sort) throws SystemException;
e.g. searching for Users by 'company-name' attribute
LinkedHashMap userParams = new LinkedHashMap();
userParams.put("usersOrgs", new Long(organizationId));
userParams.put("company-name", "My Company");
boolean asc = true;
Sort sort = new Sort("lastName", Sort.STRING_TYPE, asc);
Hits hits = UserLocalServiceUtil.search(
companyId, null, true, userParams, 0, 20, sort);
List<User> users = new ArrayList<User>();
List<Document> hitsList = hits.toList();
for (Document doc : hitsList) {
long userId = GetterUtil.getLong(doc.get(Field.USER_ID));
users.add(UserLocalServiceUtil.getUserById(userId));
}
e.g. searching for users where a value can be found in any indexed field, as well as in custom attributes
LinkedHashMap userParams = new LinkedHashMap();
userParams.put("usersOrgs", new Long(organizationId));
boolean asc = true;
Sort sort = new Sort("lastName", Sort.STRING_TYPE, asc);
Hits hits = UserLocalServiceUtil.search(
companyId, "My Company", true, userParams, 0, 20, sort);
List<User> users = new ArrayList<User>();
List<Document> hitsList = hits.toList();
for (Document doc : hitsList) {
long userId = GetterUtil.getLong(doc.get(Field.USER_ID));
users.add(UserLocalServiceUtil.getUserById(userId));
}
Setting the value for a specific user programatically. #
user.getExpandoBridge().setAttribute("company-name", "My Company"); 54279 Accesos