Custom Theme and Feature Stapling via WSP files

Looking to deploy a custom theme in a solution file? Here’s how to modify the SPThemes.xml file programmatically using Linq to XML. The only thing missing would be clean-up of sites using the theme upon uninstall.

http://blogs.msdn.com/ketaanhs/archive/2009/07/01/modifying-spthemes-xml-programmatically-to-deploy-new-themes-moss-2007-wss-3-0.aspx
Recently used this for a client along with feature stapling to deploy a custom theme and then force all newly created sites to use the theme. I used the WSPBuilder templates for VS2008 (I prefer these above the templates VsWSS).

Step 1: Create a WebApplication scoped feature to handle the FeatureStapling and create a SPFeatureReceiver for the feature to install the feature into the SPThemes file using the technique above.

<Feature xmlns="http://schemas.microsoft.com/sharepoint/"
         Creator="Chris Quick, Tribridge"
         Description="Forces default Client branding for all sites"
         Hidden="false"
         Id="9DEE24AC-1FF9-4fb3-AC07-2A0D9D616D99"
         Scope="WebApplication"
         Title="Client Default Branding"
         Version="1.0.0.0"
         ReceiverAssembly="Client.SharePoint.Branding, Version=1.0.0.0, Culture=neutral, PublicKeyToken=7622be71ccc3f186"
         ReceiverClass="Client.SharePoint.Branding.ClientThemeInstaller">
  <ElementManifests>
    <ElementManifest Location="elements.xml"/>
  </ElementManifests>
</Feature>

Step 2: Setup feature stapling in your ElementManifest file. Make sure the ID of the feature to staple is the ID of the feature that applies the branding (created next).

<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <FeatureSiteTemplateAssociation Id="FA5FE9BA-8DCB-40c8-950B-517AC11FCC23" TemplateName="GLOBAL"/>
  <FeatureSiteTemplateAssociation Id="FA5FE9BA-8DCB-40c8-950B-517AC11FCC23" TemplateName="STS#1"/>
</Elements>

Step 3:Create another feature scoped to the Web that will have a feature receiver using a co-worker’s method of applying a theme.

<Feature xmlns="http://schemas.microsoft.com/sharepoint/"
         Creator="Chris Quick, Tribridge"
         Description="Applies Branding to New Sites for Client"
         Id="FA5FE9BA-8DCB-40c8-950B-517AC11FCC23"
         Hidden="False"
         Scope="Web"
         Title="Client Branding Receiver"
         Version="1.0.0.0"
         ReceiverAssembly="Client.SharePoint.Branding, Version=1.0.0.0, Culture=neutral, PublicKeyToken=7622be71ccc3f186"
         ReceiverClass="Client.SharePoint.Branding.ClientBrandFeatureReceiver">  
</Feature>
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint;


namespace Client.SharePoint.Branding
{
    class ClientBrandFeatureReceiver : SPFeatureReceiver
    {
        public override void FeatureActivated(SPFeatureReceiverProperties properties)
        {
            SPWeb currentWeb = (SPWeb)properties.Feature.Parent;
            currentWeb.AllowUnsafeUpdates = true;
            currentWeb.ApplyTheme("Client");
            currentWeb.SiteLogoUrl = "/_layouts/images/Client/Client-logo.gif";
            currentWeb.Update();
            currentWeb.AllowUnsafeUpdates = false;
            currentWeb.Dispose();
        }

        public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
        {
            SPWeb currentWeb = (SPWeb)properties.Feature.Parent;
            currentWeb.AllowUnsafeUpdates = true;
            string theme = currentWeb.Theme;
            string logoUrl = currentWeb.SiteLogoUrl;
            currentWeb.ApplyTheme("none");
            currentWeb.SiteLogoUrl = "/_layouts/images/titlegraphic.gif";
            currentWeb.Update();
            currentWeb.AllowUnsafeUpdates = false;
            currentWeb.Dispose();
        }

        public override void FeatureInstalled(SPFeatureReceiverProperties properties)
        {
            // Not being used
        }

        public override void FeatureUninstalling(SPFeatureReceiverProperties properties)
        {
            // Not being used
        }
    }
}

I’m also taking the opportunity to apply the client’s default logo for the site upon activation of the feature.

Step 4: Put your theme into the solution and make sure it deploys to the TEMPLATE/THEMES folder and place any images into the appropriate folders within TEMPLATE/IMAGES.

Step 5: Build the WSP and deploy to SharePoint for testing. You will need to activate the feature on the Web Application before creating any new sites. When you create new sites, the feature should automatically be activated to deploy the custom theme branding to all news sites on that web application. There is plenty of room for improvement, so comments are welcome!

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s