Thursday, January 26, 2006

Extreme SharePoint Design: Customizing SharePoint Administration Pages

Administration pages in SharePoint are often the Achilles heel of a customized portal design – they exist outside of the site definition framework, they don’t inherit templates, and they implement a confusing array of shared code structures. This can create usability issues as users switch from a cohesive design on default and list pages to the default GUI and navigation when trying to create a new list or add an alert.

Depending on your design, customizing administration pages can quickly become a nightmare – if just modifying the header is not enough then you’re in for a bumpy road ahead. Here are a few tips that can help you get from stock to custom without the need for a morphine I.V. drip:

Primary Page Structures

There are 215 .ASPX files in the /layouts/1033 directory. Seventy-eight percent of these fall into one of two primary code structures. For simplicity, we’ll call them the ‘SPS’ style and ‘WSS’ style. The SPS style relies upon a server-control structure to render page content; the WSS style uses more traditional HTML code to display content.

The following code renders the page header in the SPS style:

This is how the same header is retrieved in the WSS style:

The most important difference between the two files is the WSS style’s utilization of the AlternateHeader property. The code first checks to see if an alternate header exists – either PORTALHEADER.ASPX or ALTERNATEHEADER.ASPX – and, if so, retrieves the code from the file and renders it; if not, it renders the code between the if…else blocks. This is a useful mechanism because the alternate header files function the same way as a user control – a central file that can be modified to match the new portal design scheme and is accessed from many pages – but it’s only applicable to the WSS style. How do we apply this same concept to the SPS style?

User Controls

Directly modifying the SPS style pages to replace the header is pretty straightforward – just replace the contents between the SPSWC:PageHeader tags (if you aren’t going to use the SPSWC:CategoryNavigationWebPart control in your code, be sure to leave it in place and comment it out). The problem is that there are 67 of these files so maintaining the customized code can become an issue. The solution is to implement a user control to replace the default code and duplicate the alternate header functionality. But there is a catch (naturally).

Pages in the /layouts/1033 directory can utilize external code files but only if they reside in the same directory. So, unlike site defintion files, for which user controls are normally stored in the virtual server /bin directory, any controls created for administration pages must be stored in /layouts/1033; otherwise, the process is the same. Create the replacement code, save it in an .ASCX file in the /layouts/1033 directory, and reference it from each administration page.

First, remember that when creating a user control you need the correct page registrations for any code contained within the file. The standard registrations are:

<%@ Control Language="c#" AutoEventWireup="false" TargetSchema="http://schemas.microsoft.com/intellisense/ie5"%>;
<%@ Register Tagprefix="WebPartPages" Namespace="Microsoft.SharePoint.WebPartPages" Assembly="Microsoft.SharePoint, Version=11.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"%>
<%@ Register Tagprefix="SPSWC" Namespace="Microsoft.SharePoint.Portal.WebControls" Assembly="Microsoft.SharePoint.Portal, Version=11.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"%>
<%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=11.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"%>
<%@ Register Tagprefix="Utilities" Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint, Version=11.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"%>

You’ll also need to register the new user control at the top of each administration page, like this:

<%@ Register Tagprefix="CUSTOMUC" Tagname="spsPortalHeader" src="spsPortalHeader.ascx"%>

You can then call the code from within the page by placing the user control reference between the SPSWC:TopPageSection tags. For example:

<CUSTOMUC:spsPortalHeader id="spsPortalHeader" runat="server"></CUSTOMUC:spsPortalHeader>

Of course, you still have to modify all 67 SPS style pages but by implementing user controls you only have to do this once; after that, you make changes only to the .ASCX file and they will be propagated automatically.

Beyond Headers

Sadly, replacing headers is the easiest part of administration file customization. Beyond that you enter into the realm of painful line-by-line replacement. WSS style pages are a bit easier as you have direct access to the page body code, which can be edited easily enough (user controls can also save you some headaches here), but watch out – the structures change slightly from page to page and there are often hard-coded elements (such as page titles) so be careful how much editing you do. The same can’t be said for SPS style pages – they use nothing but server controls to render code.

The good news on both fronts is that creative manipulation of style sheets can overcome most design challenges, as long as you’re willing to live with the boxy and boring standard white content area. The primary styles in play here are ms-nav, ms-navframe, ms-titlearea, ms-titleareaframe, ms-titlearealine, ms-verticaldots, ms-colspace, ms-pageidi, ms-pageidpt, and ms-pageidta. You’ll also have to deal with the stock images at the top of the left column by moving them around or making them disappear altogether. Assuming you’ve already modified the styles for the navigation frame on the left and the associated menus, you should be well on your way to improving the bland look of those finicky administration pages.

Happy SharePointing!

UPDATE: Need to get rid of that pesky image at the top of the left column in the SPS style? Try Mike Rundle's text-hiding method. Add this to your style sheet:

.ms-pageidi
{ text-align: -100px }

Image be gone! (Note: it's still there, the text-align setting just moves it off the page where it can't be seen)