Dev Notes

Notes on Development with Microsoft Technologies

Custom Theme and Feature Stapling via WSP files

Leave a comment

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

Author: Chris Quick

I have been a developer of web based solutions since early 2001 delivering solutions to a wide array of organizations using ASP, ASP.NET and SharePoint. I was introduced to SharePoint in 2003 when the consulting firm I worked for at the time introduced it into the workplace. I began working with MOSS 2007 as soon as Microsoft released the RTM version in November 2006. The platform was implemented at the organization I worked for in 2007 and went live in March of that year. I was tasked with the administration and ongoing development of the platform. I currently work as a SharePoint Architect with Artis Consulting, developing solutions for a wide variety of business problems. The goal of this blog is to share my discoveries developing solutions with SharePoint. I welcome your comments and feedback to any post -- and I welcome suggestions for future topics.

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