Please upgrade your web browser now. Internet Explorer 6 is no longer supported.
Zac Smith
SharePoint, WSS and MOSS development.

How to Customize the User Information Page (Part 3)

by Zac Smith 30-Oct-07, 24 Comments
UPDATED: Changed the Edit Button to override the default SP edit button to fix edit link bug. The sample solution has been updated to reflect the changes.
 
Continuing on from the User Information page customization series:
 
Part 1 talked about some of the difficulties presented with application pages in general.
Part 2 demonstrated how to redirect the user to a custom User Profile page using feature deployment.
This part will show how you can simply customize the look and feel of the User Profile page. Before reading this part you should read Part 2 and have a look at the sample code.
 
I am going to focus on the more significant changes - all the HTML/CSS changes including the custom master page have been left out (The code used is included in the sample solution though).
 
In order to reuse as much of what SharePoint provides as possible - I will base my customized User Profile page on the SharePoint userdisp.aspx page.
 
The first thing to do is to turn the userprofile.aspx page created in Part 2 into code behind page that extends the UserDisplayEditPageBase. To do this, create a class like so:
public class UserProfilePage : UserDisplayEditPageBase
 
To resolve the UserDisplayEditPageBase class you need a reference to Microsoft.SharePoint.ApplicationPages.dll which is not in the GAC. You will need to Browse to the location "C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\CONFIG\BIN" to find this dll.
I have included the dll in the sample source code for simplicity.
 
Now I will update my custom profile page to inherit from this  class:
<%@ Page Language="C#" Inherits="CustomUserProfile.UserProfilePage, CustomUserProfile, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1ba1bfabc83c4398" MasterPageFile="~/_layouts/application.master" %>
 
Note that that I have used the fully qualified name and this assumes that the dll will be signed and placed in the GAC. See the sample solution for how this can be easily done.
 
Now put the contents of the original userdisp.aspx (from the 12 Hive) into the userprofile.aspx page. The first modification to make is to remove the delegate control in the custom page or so you don't get stuck in an infinite redirect loop.
 
At this point I could just apply a custom master page and be done. This would let me easily apply a new look and feel, but I'd like to make a few modifcations to the layout as well.
 
You will probably have already noticed that the guts of the page are contained in a FormComponent control. This control provides a set of properties and methods that make it easy to display a form based on a SharePoint list item. It's rendering is controlled by the TemplateName property which is currently set to 'UserListForm'. We can find the contents of this form by looking in c:\program files\common files\microsoft shared\web server extensions\12\template\controltemplates\DefaultTemplates.ascx. I don't want to modify this file directly (it will affect all SharePoint sites) so I will take a copy of the SharePoint:RenderingTemplate and put it in a new ascx file named CustomTemplates.ascx (this will live in the controltemplates dir). I then give it a custom name so that it only overrides it for the profile display page. Now I should have a FormComponent in my profile page like:
<SharePoint:FormComponent id="UserListForm" TemplateName="CustomUserListForm" ControlMode="Display" runat="server"/>
and in CustomTemplates.ascx file I have:
<SharePoint:RenderingTemplate ID="CustomUserListForm" runat="server">
 
<Template>
   
<span id="part1">
      .....
 
Note that the TemplateName of the FormComponent matches up with the ID off the RenderingTemplate.
From here it is easy enough to edit some of the basic HTML elements of the form.
 
Next up is to customize the Toolbar. To do this copy the RenderingTemplate with the ID of "UserInfoListDisplayFormToolBar" from DefaultTemplates.ascx to the CustomTemplates.ascx file. I want to remove some of the buttons and have a custom Edit Item button so I can link to a custom user profile edit page. To do this change the control declaration from:
<SharePoint:UserInfoListFormToolBar runat="server"/>
to
<SharePoint:FormComponent id="UserToolBar" TemplateName="CustomUserInfoListDisplayFormToolBar" runat="server"/>
 
And then customize the RenderingTemplate like so:
<SharePoint:RenderingTemplate ID="CustomUserInfoListDisplayFormToolBar" runat="server">
<Template>
 
<script>
   
recycleBinEnabled = <SharePoint:ProjectProperty Property="RecycleBinEnabled" runat="server"/>;
 
</script>

 
<wssuc:ToolBar CssClass="ms-toolbar" id="toolBarTbl" runat="server" FocusOnToolbar="true">
   
<Template_Buttons>
     
<prof:UserProfileEditButton ID="UserProfileEditButton1" runat="server" />       <SharePoint:UserInfoListDeleteItemButton ID="UserInfoListDeleteItemButton1" runat="server"/>
   
</Template_Buttons>
 
</wssuc:ToolBar>
</Template>
</
SharePoint:RenderingTemplate>
 
Note that I have removed a few of the buttons for alerts and regional settings as well as create a custom button for linking to the useredit.aspx. 
The custom edit button simply overrides the standard SharePoint edit button and updates the URL:

public class UserProfileEditButton : UserInfoListEditItemButton
{
  protected override void OnLoad(EventArgs
e)
  {
    base
.OnLoad(e);
    base.NavigateUrl = base.NavigateUrl.Replace("useredit", "usermodify"
);
  }
}

Next I want to tidy up up the user display name as it includes the domain and won't have any meaning for most users.
To do this I override the OnPreRender method in the UserProfilePage class created earlier:
protected override void OnPreRender(EventArgs e)
{
 
base.LabelTitle.Text = base.UserListForm.ListItem.GetFormattedValue("Title"
);
}
This will give us a nicer looking display name:
User Info
 
 
In this case I don't want to display the SIP Address, so the next task is to remove this from the profile page. Currently all of the fields are rendered using a FieldIterator which is declared on the page as:
<SharePoint:ListFieldIterator runat="server"/>
 
In order to customize how the user list fields are displayed - we need to create a class that overrides the ListFieldIterator. My class is declared like this:
public class UserProfileFieldIterator : ListFieldIterator
 
Becuase I want to exclude the SIP Address I am then going to add override the IsFieldExcluded method like so:
protected override bool IsFieldExcluded(SPField field)
{
  if (field.Title == "SIP Address")
    return true;

  return base.IsFieldExcluded(field);
}

To replace the existing field Iterator currently being used I need to first register the assembly:
<%@ Register TagPrefix="prof" Namespace="CustomUserProfile" Assembly="CustomUserProfile, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1ba1bfabc83c4398" %>
 
and then replace the field iterator declaration with the custom one just made:
<prof:UserProfileFieldIterator ID="UserIterator" runat="server" />
 
The last thing I'm going to do is attach the custom master page. This is simply a case of changing userprofile.aspx to point to a new master page:

<%@ Page Language="C#" Inherits="CustomUserProfile.UserProfilePage, CustomUserProfile, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1ba1bfabc83c4398" MasterPageFile="~/_layouts/customprofile.master" %>

The custom master page also requires a couple of css files to override and add styles to the SharePoint page.
 
And now after all our hard work - "The final product":
custom user profile page
 
You can download the sample code (including solution deployment) -> here.
 
Although I have only customized the SharePoint user info page you can do the same for the edit page - or any application page really.
 
I am considering doing a Part 4 with some advanced customizations such as having a custom action when closing the page (eg redirect) and modifying some of the form fields. Let me know if this is something that you are interested in.
 
For more information on Form Components, Rendering Templates and List Iterators have a look at the following resource:
 
Categories:
24 responses so far:
  • Sunday, 31 May 2009 08:19 by Tristan
    Absolutely fantastic post! I felt the same way regarding modification of the OOB sharepoint files (as in Liam Cleary's solution), so this method seemed like an ideal approach. I have implemented something similar, and it works like a charm!
  • Sunday, 31 May 2009 08:19 by Bruno Correa
    Very good! It would be nice if you could post a Part 4, including a 'usermodify.aspx' page.
  • Sunday, 31 May 2009 08:19 by VMAtm
    Hi, Zac. How about part 4? Did you forget about it or not?
  • Sunday, 31 May 2009 08:19 by Zac Smith
    Definately havent forgot, its more a matter of finding the time to put the post together. Will endeavour to get something up in the next few weeks.
  • Sunday, 31 May 2009 08:19 by VMAtm
    Main question is - how to define SPControlMode for the controls are generating for the user property (for example, I need to show property value, but no need changes in this property) Wait for it with great respect :)
  • Sunday, 31 May 2009 08:19 by Anders Jacobsen
    An alternative to change the master would be to use an approach as I have suggested at: . This implementation uses a HTTPModule to dynamically and non-intrusive change the Master and/or the CSS.
  • I tried a simple excludefields entry '' in '' under the defaulttemplates.ascx file and a IISreset...but that didn't seem to work... any reason why?
  • Sunday, 31 May 2009 08:19 by
    I tried a simple excludefields entry '' in '' under the defaulttemplates.ascx file and a IISreset...but that didn't seem to work... any reason why?
  • Sunday, 31 May 2009 08:19 by Fred
    I tried a simple excludefields entry '' in '' under the defaulttemplates.ascx file and a IISreset...but that didn't seem to work... any reason why?
  • Sunday, 31 May 2009 08:19 by ocean
    Hello Zac, I have a question. I use aspnetsqlmemebership provider and form authentication, and I find no admin users have no rights to change their own user profile. and when I deployed your solution. admin users visit very well, but common user visit userprofile.aspx will get an unhandled error. can you tell me how to set the rights? thanks.
  • Sunday, 31 May 2009 08:19 by Kieran
    Hi Zac Did you ever get round to writing up anything on changing the OSSSearchResults.aspx page? You mentioned it in Part 1 but I dont see any other related posts. Many Thanks
  • Sunday, 31 May 2009 08:19 by Mohamed
    The links appear in the top of this post for Page 1 and Page 2 are broken, Could you link them to right article? Thanks.
  • Sunday, 31 May 2009 08:19 by Sanjiv
    I am getting the below error when I diplaoyed the code, Please let me know if I am missing anythinng else:- The directive 'control' is unknown. at System.Web.UI.TemplateParser.ProcessError(String message) at System.Web.UI.TemplateParser.ProcessDirective(String directiveName, IDictionary directive) at System.Web.UI.BaseTemplateParser.ProcessDirective(String directiveName, IDictionary directive) at System.Web.UI.TemplateControlParser.ProcessDirective(String directiveName, IDictionary directive) at System.Web.UI.PageParser.ProcessDirective(String directiveName, IDictionary directive) at System.Web.UI.TemplateParser.ParseStringInternal(String text, Encoding fileEncoding)
  • Sunday, 31 May 2009 08:19 by Doug
    Subscribe with RSS SharePoint Team Blog Chandima Kulathilake Andrew Connell Ari Bakker ECM Team Blog Daniel Larson Ian Morrish Liam Cleary Vincent Rothwell SPD Team Blog April 2009 (2) March 2009 (2) October 2008 (1) September 2008 (1) August 2008 (2) July 2008 (2) June 2008 (1) May 2008 (2) April 2008 (1) March 2008 (3) February 2008 (4) January 2008 (2) November 2007 (1) October 2007 (8) September 2007 (4) August 2007 (3) July 2007 (4) June 2007 (2) May 2007 (4) April 2007 (5) March 2007 (1) How to Customize the User Information Page (Part 1) by sa_StgMOSSAdmin, 14-Oct-07, 2 Comments This 3 part post series discusses how you would go about customizing the user profile page accessed from the "My Settings" link in the welcome menu. That's this page here: Although it seems like a simple task, there is actually quite a lot to consider. I am also planning to demonstrate a number of useful SharePoint techniques along the way. The first part is about application pages in general and why they cause headaches for designers trying to customize the look and feel of SharePoint. Application Pages One of the first things people want to do after installing SharePoint - is to make it look like anything but SharePoint. If you have ever been involved in skinning a SharePoint/WSS site you will know the difficulties posed by application pages. These are the pages in the "_layouts" directory that are shared across all SharePoint sites. It is always recommended to NOT edit these files as all web applications will be affected by the changes. This is not a problem for most application pages as they are generally only accessed by site administrators. There are however a few application pages that are viewable by all users. It can be very frustrating to find that after you have gone to all the trouble of skinning a SharePoint site only to find that a few pages still render that standard SharePoint blue. Two commonly problematic pages are: UserDisp.aspx This is the user profile page shown in the above screenshot, it links to a number of other application pages such as UserEdit.aspx. The page is accessible by any authenticated user. It is also the focus of this post series. SearchResults.aspx The standard WSS search page. In MOSS there is also the osssearchresults.aspx page for the standard "This List" and "This Site" search scopes. There are a few techniques that can be used to customize these pages. The easiest way would be to simply manipulate the pages in the LAYOUTS directory. Obviously any changes made are going to affect all your SharePoint sites. It also presents a problem during deployment, how are these changes going to be packaged up to make releases easy? What if there are multiple front end servers? And what happens when a service pack comes out that has new versions of these pages? Its probable that your changes will be overwritten. Luckily the creators of SharePoint had foreseen these issues and in most cases have provided a way to customize these pages safely. More about this in Part 2. Part 2 will demonstrate how we can manipulate the My Settings Link Categories: 2 Comments: Friday, 1 Feb 2008 12:26 by Kermit Thanks Zac. Just thought it might be useful to have a direct link to the part two page here. Sunday, 5 Apr 2009 08:27 by Doug Links to all parts in this series (I found them difficult to track down - the links on part 3 don't work for parts 1 and 2): http://www.trinkit.co.nz/blog/archive/2007/10/09/how-to-customize-the-user-profile-display-page-part-1.aspx http://www.trinkit.co.nz/blog/archive/2007/10/15/how-to-customize-the-user-information-page-part-2.aspx http://www.trinkit.co.nz/blog/archive/2007/10/30/how-to-customize-the-user-information-page-part-3.aspx
  • Sunday, 31 May 2009 08:19 by Ben
    so... how does this affect all other sites hosted on the SP box? What happens to your MS support agreement? What happens when a service pack updates this page... It's really Not a good idea to customise the OOTB admin pages in SP... Think MOSS instead with User Profile pages
  • Sunday, 31 May 2009 08:19 by Zac Smith
    Ben, I think you may have missed the key point to the whole article series. If you actually read through and understand the method of customization you will see that this solution does not affect any of the OOTB admin pages. It does not affect other sites hosted on the box, it should not affect your MS support, service updates are no problem. I don't see how suggesting MOSS is a solution - for many people MOSS is not a viable option.
  • Sunday, 31 May 2009 08:19 by Frederik
    Its a great example but im missing something. In this line you redirect to useredit.aspx but where is the ID?
  • Sunday, 31 May 2009 08:19 by Frederik
    Sorry! The line is meant to the line where you set up the Edit Item button. You onlu redirect to the useredit.aspx, but you need a ID of the user
  • Sunday, 31 May 2009 08:19 by Zac Smith
    Yes that was a bit of an oversight in the example - I have updated the post to address this issue.
  • Wednesday, 2 Sep 2009 05:41 by Shridha Agarwal
    Hi Zac ! You seem to have forgotten the part 4 of the series. Waiting for it.
  • Wednesday, 9 Dec 2009 03:23 by Brian Johannesen
    Hi Zac , great articles you made here.. Hope you will have time to do the 4th one as well :)
  • Friday, 18 Dec 2009 05:38 by Tom K
    Zac - a thousand thanks! All roads I could find on this matter keep coming back to you ... a great testament to your solution :-) To note, with regards to Visual Studio 2010 (beta, at least at the time of this writing) ... when I import your solution the Microsoft.Sharepoint assembly gets 'disabled' of sorts ... only after reimporting (from the \\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\ISAPI folder) and upping the Target Framework to 3.0 or 3.5 will your solution properly build. Just an fyi for anyone who may have been traveling down the road I was ... Thanks again! Looking forward to part 4! :-)
  • Friday, 19 Feb 2010 06:53 by santhosh
    Thanks for the post. I wanted to exclude Account from the list. But not able to do that.I could exclude all other fields . Is there any workarounds? Thanks
  • Tuesday, 9 Mar 2010 03:26 by Dan G
    That's a cool solution, just started using Sharepoint and must admit the customisation side of things is a right pain.

 

Post a Comment:
Name:
URL:
Email:
Comments: