Vinny Khosla asked on the JASIG-PORTAL list:
How do i setup a user layout template?
Subsequently, how do I go about creating subsequent user accounts who would inherit the layout template?
Could you please tell me what tables, columns and xml files are involved
here?
Do the new users automatically inherit the layout template?
or Is there a way to force a new user to inherit a certain custom layout
template ?
Answer (credit due to Susan Bramhall for initially posting reponse on JASIG-PORTAL):
The easiest way to create a template is to use ant md5passwd to create the account then login and use the GUI to set up the layout you want.
To map a user to use the template use the PersonDirs.xml to map the some appropriate attribute to uPortalTemplateUserName. The login process for the user will select the layout that matches the value of the uPortalTemplateUserName person attribute.
For example:
<uidquery>select first_name||' '||Last_name first_last, decode(role,'UNDERGRADUATE','student', 'GRAD_STUDENT','student', 'MP', 'staff', 'CT', 'staff', 'CAS', 'staff', 'SM', 'staff', 'FAC_LADDER','faculty', 'FAC_NON-LADDER','faculty', 'VF','faculty', 'FEL','faculty', 'PDA','faculty', 'PDF','faculty', 'proto-user') template, from portal_person_directory where netid=?</uidquery> with attribute template mapped like this: <attribute> <name>template</name> <alias>uPortalTemplateUserName</alias> </attribute>
This would cause the value of "role" from the sql query to govern the choice of template. This is a snippet from our actual configuration.
Behind the scenes
The IUserIdentityStore interface is the mechanism for retrieving the unique identifier for the current user in the portal. There is one implementation of this interfact: RDBMUserIdentityStore
. Two properties as well as the value of person attributes for the user affect how this class makes the choice of template.
- The property
autoCreateUsers
turns template behavior on or off. As distributed the property is set:When set to true,org.jasig.portal.services.Authentication.autoCreateUsers=true
RDBMUserIdentityStore
will automatically create all necessary data for a new portal user based on a template user. If set to false users data will not be automatically created. So far there is no other mechanism for creating user data so this property is always set to true.
- The template user value is determined either by the property
defaultTemplateUserName
or by mapping a directory attribute to uPortalTemplateUserName. When a user logs in for the first time,RDBMUserIdentityStore
first looks for a person attribute nameduPortalTemplateUserName
. The value of that attribute is expected to be the username of an existing user. The existing user is then the template for the new user. If no attribute is of that name is mapped the template user name comes from the propertyorg.jasig.portal.services.Authentication.defaultTemplateUserName
. In the distribution this is set to the userdemo
:This means that if you make no changes and map no attribute to uPortalTemplateUserName then all new users will be cloned from the userorg.jasig.portal.services.Authentication.defaultTemplateUserName=demo
demo
.
Templates and layout managers
Simple layout manager (SLM) derives power and flexability from using templates to deliver different content to users based on the values in the person object. However, once a user changes this or her layout a copy is stored and the template is no longer used. So any changes to the template after the user has personalized his or her layout do not appear unless the user resets to the default. Likewise, any change of mapping from user to template user (i.e., cahnges the the value of the template user person attribute for a given person) has no effect once the user has his or her very own copy of layout by having personalized. Since both aggregated layout manager (ALM) and distributed layout manager (DLM) have better mechanisms for pushing content to users, templates can be minimized or eliminated entirely when simple layout manager is not used.
When the template mapping changes
Any given user is either 1) linked to a template user and without a layout of his own, or 2) unlinked from the template and using her very own layout. Users start out linked to their template users. They become unlinked by means of making a layout personalization, e.g. adding, moving, or deleting a channel. On personalization, uPortal copies the template layout content into a new personal layout for this user, and forevermore this user is "unlinked" from the template (until and unless the user resets layout.)
If a user is unlinked from the template layout, then neither changes to the content of the template layout nor changes to the user attribute that determined to which template the user is mapped have any effect.
If a user is linked to a template layout, then when this user's linked template user's layout changes, those changes are reflected in the perceived layout of the user. Since the user didn't have a layout of her own, she is using the template user's layout, and so experiences updates to that template on next login.
But what happens when the user's template attribute itself changes, for example the value changes from "student" to "faculty"? If the user is linked to a template layout, the portal will display the new template user layout (in this case, faculty), delete this user from all the modifiable groups in which she presently resides, and place this user in the new groups associated with the faculty template user. However, if the user is unlinked from the template, the change to template attribute will have no effect (until and unless the user resets her layout).
To restate, providing the user does not customize his or her layout, when the user's portal template attribute values changes, the portal will present the new layout and pull the user out of all past groups that it can (cannot modify read-only groups such as PAGS groups) and place this user into the new groups affiliated with the new template user, whereas in the event that a user modifies his or her layout and thereby breaks association with the template user, then even if the portal template attribute changes, the user will not receive a new layout nor will she change group membership.
Source code snippets implementing the described behavior
boolean hasSavedLayout = userHasSavedLayout(portalUser.getUserId()); if (!hasSavedLayout) { TemplateUser templateUser = getTemplateUser(templateName); if (portalUser.getDefaultUserId() != templateUser.getUserId()) { //Update user data with new template user's data updateUser(portalUser.getUserId(), person, templateUser); } }
protected void updateUser(int userId, IPerson person, TemplateUser templateUser) throws Exception { // Remove my existing group memberships IGroupMember me = GroupService.getGroupMember(person.getEntityIdentifier()); Iterator myExistingGroups = me.getContainingGroups(); while (myExistingGroups.hasNext()) { IEntityGroup eg = (IEntityGroup)myExistingGroups.next(); ILockableEntityGroup leg = GroupService.findLockableGroup(eg.getKey(), me.getKey()); removePersonFromGroup(person, me, leg); } // Copy template user's groups memberships IGroupMember template = GroupService.getEntity(templateUser.getUserName(), Class.forName("org.jasig.portal.security.IPerson")); Iterator templateGroups = template.getContainingGroups(); while (templateGroups.hasNext()) { IEntityGroup eg = (IEntityGroup)templateGroups.next(); ILockableEntityGroup leg = GroupService.findLockableGroup(eg.getKey(), me.getKey()); addPersonToGroup(person, me, leg); }