One often under-appreciated feature of Windows SharePoint Services is the DelegateControl. This is new to WSS v3, and provides an excellent method of customization without touching the default SharePoint pages. Using delegate controls, we can easily customize or replace many of the default SharePoint pages and user controls, including those that are found in many disparate locations (such as the search bar). Many of the SharePoint pages have a reference for a DelegateControl, as follows:
<SharePoint:DelegateControl runat="server" id="DelctlProfileRedirection" ControlId="ProfileRedirection" Scope="Farm" />
This particular example is a reference from the userdisp.aspx page (located in c:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\TEMPLATE\LAYOUTS), which controls the display of the user profile details (available via Welcome > My Settings). Other files with references to Delegate Controls in the LAYOUTS directory include:
- AddNavigationLinkDialog.aspx: ControlId=”AddNavigationLinkDialogPanel1″ Scope=”Site”
- AddNavigationLinkDialog.aspx: ControlId=”AddNavigationLinkDialogPanel2″ Scope=”Web”
- AreaNavigationSettings.aspx: ControlId=”NavigationSettingsPanel1″ Scope=”Site”
- AreaNavigationSettings.aspx: ControlId=”NavigationSettingsPanel2″ Scope=”Web”
- BackLinks.aspx: ControlId=”SmallSearchInputBox”
- ExcelProfilePage.aspx: ControlId=”VariationsFlagControl”
- ExcelProfilePage.aspx: ControlId=”GlobalSiteLink1″ Scope=”Farm”
- ExcelProfilePage.aspx: ControlId=”GlobalSiteLink2″ Scope=”Farm”
- groups.aspx: ControlId=”QuickLaunchDataSource”
- listcontentsources.aspx: ControlId=”QuickLaunchDataSource”
- listservernamemappings.aspx: ControlId=”QuickLaunchDataSource”
- logsummary.aspx: ControlId=”QuickLaunchDataSource”
- logviewer.aspx: ControlId=”QuickLaunchDataSource”
- managecrawlrules.aspx: ControlId=”QuickLaunchDataSource”
- managefiletypes.aspx: ControlId=”QuickLaunchDataSource”
- manageprivacypolicy.aspx: ControlId=”QuickLaunchDataSource”
- manageservicepermissions.aspx: ControlId=”QuickLaunchDataSource”
- mycontactlinks.aspx: ControlId=”ColleaguesLink1″ Scope=”Farm”
- newsbweb.aspx: ControlId=”CreateSitePanel1″ Scope=”Site”
- people.aspx: ControlId=”QuickLaunchDataSource”
- personalsites.aspx: ControlId=”QuickLaunchDataSource”
- profmain.aspx: ControlId=”QuickLaunchDataSource”
- quicklinks.aspx: ControlId=”AddColleaguesLink1″ Scope=”Farm”
- regionalsetng.aspx: ControlId=”RegionalSettingsExtensions”
- schema.aspx: ControlId=”QuickLaunchDataSource”
- scsignup.aspx: ControlId=”CreateSiteCollectionPanel1″ Scope=”Farm” />
- searchsspsettings.aspx: ControlId=”QuickLaunchDataSource”
- SiteManager.aspx: ControlId=”GlobalSiteLink1″ Scope=”Farm”
- SiteManager.aspx: ControlId=”GlobalSiteLink2″ Scope=”Farm”
- user.aspx: ControlId=”QuickLaunchDataSource”
- userdisp.aspx: ControlId=”ProfileRedirection” Scope=”Farm”
- VersionDiff.aspx: ControlId=”SmallSearchInputBox”
- viewlsts.aspx: ControlId=”QuickLaunchDataSource”
- viewscopes.aspx: ControlId=”QuickLaunchDataSource”
- XLViewer.aspx: ControlId=”GlobalSiteLink1″ Scope=”Farm”
- XLViewer.aspx: ControlId=”GlobalSiteLink2″ Scope=”Farm”
However, lets get back to that userdisp.aspx page. I chose this reference because it ties in nicely with my previous posts as a next step in learning about WSS and MOSS user profiles. As you can see from the example above, this is a SharePoint-specific meta tag, which has two important attributes:
- ControlId – This attribute provides the unique identifier that will be referenced by any delegate control implementations which will tie them to this location.
- Scope – This attribute indicates the feature scope where SharePoint will look for delegates.
This meta-tag provides us with a point to hook up our own custom user controls to be included with the default SharePoint content, which we will call our “custom delegate control”. The most common method of implementing a custom delegate control is through the use of features containing control templates. Let’s start by looking at this in more detail. All SharePoint features live in the TEMPLATE\FEATURES directory within the 12-hive, commonly:
c:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\TEMPLATE\FEATURES
Each feature is defined within a subdirectory, by way of an xml definition. The top-level file is always called feature.xml, and it contains the actual definition of the feature properties, such as:
<Feature Id="59BA9C79-766E-498d-AFD5-B90D6340ADDE"
Title="User Profile Details"
Description=""
Version="1.0.0.0"
Scope="Farm"
xmlns="http://schemas.microsoft.com/sharepoint/">
<ElementManifests>
<ElementManifest Location="UserProfileElements.xml"/>
</ElementManifests>
Since this post is NOT about features, I won’t go into too much detail here. Rather, it is important to note that the Scope attribute defined here MUST match the Scope attribute defined by the SharePoint:DelegateControl reference. Possible values for Scope include:
- Farm
- Web Application
- Site Collection
- Web Site
You will also notice that within the feature.xml definition, there is reference to an Elements.xml file. This file further defines the feature by referencing any external files or assemblies that are used by the feature. An example of this Elements.xml file…
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<Control Id="ProfileRedirection" Sequence="95" ControlSrc="~/_controltemplates/UserProfileRedirect.ascx"/>
</Elements>
Notice that this example references our custom delegate control, located within the control templates directory. The Elements.xml can also point to an assembly, but we won’t go into that here. There are two important attributes to make note of in reference to SharePoint delegate controls:
- Id – This MUST match the ControlId attribute as defined in the SharePoint delegate control definition.
- Sequence – This attribute must be an integer value, and is used in the case where multiple delegate controls have been defined. The lowest sequence number with matching ControlId is always used.
So, we have our feature defined, and we have a custom delegate control defined that we want to be a delegate. Now what? Well, all we have to do is install the feature, and then SharePoint takes care of all the ControlId matching for us. Features are installed via one of the following methods:
- Manually – Installation can be performed manually by creating the feature directory within c:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\TEMPLATE\FEATURES, placing the xml files within that directory, and running the following command:
stsadm.exe –o installfeature –filename [your feature dir]\feature.xml - Using Solutions – You can also install the feature as part of a solution, by referencing it in a solution’s manifest.xml as follows…
<Solution ...>
<FeatureManifests>
<FeatureManifest Location="CISUserProfile\feature.xml"/>
</FeatureManifests>
…
<TemplateFiles>
<TemplateFile Location=”CONTROLTEMPLATES\UserProfileRedirect.ascx” />
</TemplateFiles>
</Solution>
Once we have our feature in-place (via either method above), we just need to install and activate it. The easiest method for all features scopes is to activate using the command line, as follows:
stsadm -o installfeature -filename [feature dir]\feature.xml
stsadm -o activatefeature -filename [feature dir]\feature.xml -url [site-url]
iisreset
Once that is done, your custom delegate control is in-place and ready to use! I would be remiss if I didn’t reference the sources I used while learning these concepts a short while ago myself…
http://msdn2.microsoft.com/en-us/library/ms463169.aspx
http://zac.provoke.co.nz/archive/2007/10/14/how-to-customize-the-user-profile-display-page-part-1.aspx
Happy coding!
Tristan