Wednesday, June 07, 2006

Extreme SharePoint Design: Using the AlternateHeader Property in WSS

I’ve done a number of customizations to administration pages (.aspx files located in the \LAYOUTS\1033 directory) by directly modifying the pages themselves. This is a cumbersome process, involving a lot of HTML search-and-replace operations. I felt it was time to use a more flexible approach so I attempted to create a more robust solution that works in both SPS and WSS. The first challenge to overcome was the fact that pages in a WSS context don’t inherit the AlternateHeader property from the Site Definition ONET.XML file. In the portal definitions, the following setting points the administration pages to a file called ‘PortalHeader.aspx’ and, if the file is not empty, renders the header contained therein:

< title="Team Web Site" listdir="Lists" ows="Microsoft SharePoint" alternateheader="PortalHeader.aspx" disablewebdesignfeatures="wdfbackup; wdfrestore; wdfpackageimport; wdfpackageexport; wdfthemeweb; wdfthemepage; wdfnavigationbars; wdfnavigationview; wdfpublishview; wdfpublishselectedfile; wdfNewSubSite">

This setting does not exist in the STS definition so it must be added (note that this will have no effect on existing WSS sites, only new ones created after the ONET.XML file has been modified). Unfortunately, the default PortalHeader.aspx file contains a number of < SPSWC: > control references which are portal-specific and will not render in a WSS context; simply adding this setting will not solve the problem. So the first step is to edit the ONET.XML file in TEMPLATE\1033\STS\XML to include the AlternateHeader setting and point it to a new header file, as follows:

Original code:

< title="Team Web Site" listdir="Lists" ows="Microsoft SharePoint">

Replacement code:

< title="Team Web Site" listdir="Lists" ows="Microsoft SharePoint" alternateheader="STSHeader.aspx">

Next, the new header file must be created (STSHeader.aspx in this example). This file must contain the proper WSS-context registrations to enable code execution (if necessary) and the content must be devoid of any portal-specific control references. Here is a sample STSHeader.aspx file:

< % @ Page language="C#" % >
< % @ 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" % >
< % @ Import Namespace="Microsoft.SharePoint" % >
< % @ Register Tagprefix="WebPartPages" Namespace="Microsoft.SharePoint.WebPartPages" Assembly="Microsoft.SharePoint, Version=11.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" % >

< link rel="'stylesheet'" type="'text/css'" href="'/_layouts/1033/styles/custom.css'">
< table width="100%" cellpadding="0" cellspacing="0" border="0">
< tr >
< td width="100%">
< div class="spsHeader" >
< !-- Insert Header HTML Here -- >
< % Execute Some ASP.NET Code Here % >
< /div >
< /td >
< /tr >
< /table >

After modifying the ONET.XML file and creating the new header file, copy ONET.XML to its original location and place the new header file in the \LAYOUTS\1033 directory. Perform and IISRESET on the server and create a new WSS site. Next select ‘Documents and Lists’ or ‘Create’ from the menu to see your new header code in action. If you plan to utilize custom server controls within the header file be sure to add the necessary registrations to the top of the page prior to deployment.