If you’re ever creating a custom site definition for SharePoint, it is likely that you would be required to attach a site logo to the site definition and are left wondering why such an obvious property does not exist in onet.xml. Recently I came across this situation and although the work around may be known amongst the community, it is not really well documented on the web (as I discovered while trying to find one).
The following are required for this technique:
- A site definition
- Ability to use compiled code
- A feature that is stapled to the site definition that requires the logo to be set. You can create a new one if you think that would be neater. (In this post, I’ll assume you’re creating a new feature)
First you need a feature to attach a feature receiver to. Lets assume you create a feature with the feature.xml file:
12\Features\MyProjectWebSettings\feature.xml
<?xml version="1.0" encoding="utf-8"?>
<Feature Id="373e6ca4-9f89-45e4-a2f9-dbf9d88b1af3"
Title="My Project Web Settings"
Description="Applies to the logo for the current web."
Version="12.0.0.0"
Hidden="TRUE"
Scope="Web"
DefaultResourceFile="core"
xmlns="http://schemas.microsoft.com/sharepoint/">
<ElementManifests>
</ElementManifests>
<Properties>
</Properties>
</Feature>
An important property of the feature definition has been highlighted above. The feature must be scoped at the Web level, since it will be activated every time a site is created (as opposed to site collection). If this feature is only for stapling a logo and other site settings, it should really be hidden so that it can not be reactive from the administration screen.
Next we’ll need to add a feature receiver and two properties to the feature definition. The feature receiver will allow us to write code that gets executed every time a site is created. We’ll add the following highlighted lines:
<?xml version="1.0" encoding="utf-8"?>
<Feature Id="373e6ca4-9f89-45e4-a2f9-dbf9d88b1af3"
Title="My Project Web Settings"
Description="Applies to the logo for the current web."
Version="12.0.0.0"
Hidden="TRUE"
Scope="Web"
DefaultResourceFile="core"
ReceiverAssembly="MyCompany.MyClient.MyProject, Version=1.0.0.0, Culture=neutral, PublicKeyToken=123456780abcdef"
ReceiverClass="MyCompany.MyClient.MyProject.Receivers.WebSettingsReceiver"
xmlns="http://schemas.microsoft.com/sharepoint/">
<ElementManifests>
</ElementManifests>
<Properties>
<Property Key="SiteLogoUrl" Value="/_layouts/1033/IMAGES/MyProject/Logo.gif"/>
<Property Key="SiteLogoDescription" Value="Logo alt text" />
</Properties>
</Feature>
The receiverAssembly and ReceiverClass properties define where the feature receiver code can be found. The SiteLogoUrl and SiteLogoDescription properties are there to make the logo URL and logo description manageable in the future without needing to recompile the assembly.
Next we’ll write the feature receiver class:
using Microsoft.SharePoint;
namespace MyCompany.MyClient.MyProject.Receivers
{
public class WebSettingsReceiver : SPFeatureReceiver
{
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
using (SPWeb web = (SPWeb)properties.Feature.Parent)
{
// The following code sets the appropriate property values
web.SiteLogoUrl = properties.Feature.Properties["SiteLogoUrl"].Value;
web.SiteLogoDescription = properties.Feature.Properties["SiteLogoDescription"].Value;
web.Update();
}
}
public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
{
}
public override void FeatureInstalled(SPFeatureReceiverProperties properties)
{
}
public override void FeatureUninstalling(SPFeatureReceiverProperties properties)
{
}
}
}
The last part is to bake our feature to the site definition in the onet.xml.
<Configuration>
<WebFeatures>
<!-- The ID of our feature -->
<Feature ID="373e6ca4-9f89-45e4-a2f9-dbf9d88b1af3" />
</WebFeatures>
</Configuration>
Once everything has been deployed, whenever this type of site is created, the logo and the logo description settings will be automatically set.