To be able to desploy the design created I usually end up with three basic features:
- MasterPageAdder: Adds the masterpages, css-files and all the needed images to the right places on the server/solution
- MasterPageSwitcher: Sets the default and custom masterpage file of a site to CustomMaster in code by feature activation.
- MasterPageStapler: Activates the MasterPageSwitcher for all created sites in the portal.
Here is how my project usually looks in Visual Studio:

Here I have chosen to put my Custom.css file in the Layouts\styles folder where the default css in SharePoint (Core.css) aslo are. However in some cases it might be more valuable to put it in the Style Library so that competent users at your customer more easaly can find and change it if nessecary. If you chose to do this you should deploy it using the ProvisionedFiles.xml file.
The masterpage adder feature
Consists of four files:
- Amende_dings.png: Preview image for the custom masterpage.
- AmendeCustom.master: The new masterpage
- ProvisionedFiles.xml: Puts the files where it belongs in the solution
- feature.xml: Makes everything happen
The ProvisionedFiles.xml containes information abput where to find the masterpage where to put it in the SharePoint structure (_catalogs\masterpage). It looks like this:
<?xml version="1.0" encoding="utf-8" ?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<Module Name="OSGMasterPages" Url="_catalogs/masterpage" Path="masterpage" RootWebOnly="TRUE">
<File Url="AmendeCustom.master" Type="GhostableInLibrary">
<Property Name="ContentType" Value="Custom Master Page" />
<Property Name="PublishingPreviewImage" Value="~SiteCollection/_catalogs/masterpage/$Resources:core,Culture;/Preview Images/Amende_dings.png, ~SiteCollection/_catalogs/masterpage/$Resources:core,Culture;/Preview Images/Amende_dings.png" />
</File>
</Module>
<Module Name="PublishingLayoutsPreviewImages" Url="_catalogs/masterpage" IncludeFolders="??-??" Path="" RootWebOnly="TRUE">
<File Url="Amende_dings.png" Name="Preview Images/Amende_dings.png" Type="GhostableInLibrary" />
</Module>
</Elements>
The feature.xml refferences the ProvisionedFiles.xml so that the files get copied when the feature is activated, remember to change the GUID before using the feature.xml:
<?xml version="1.0" encoding="utf-8" ?>
<Feature Id="42141f24-8ebb-4b9e-8283-8ee6e989bcce"
Title="Custom masterpage adder"
Description="Adds the custom masterpage to masterpage gallery"
Version="1.0.0.0"
Scope="Site"
Hidden="False"
DefaultResourceFile="core"
xmlns="http://schemas.microsoft.com/sharepoint/">
<ElementManifests>
<ElementManifest Location="ProvisionedFiles.xml"/>
</ElementManifests>
</Feature>
The masterpage switcher feature
The master page switcher contains of only one file, the feature.xml:
<?xml version="1.0" encoding="utf-8" ?>
<Feature Id="54705b7b-3293-4afa-be3f-8d53e032c6ef"
Title="Activates custom design (masterpage set to custom masterpage)"
Description="Switches masterpage to the custom masterpage by setting default master and custom master to custom masterpage"
Version="1.0.0.0"
Scope="Web"
Hidden="FALSE"
xmlns="http://schemas.microsoft.com/sharepoint/"
ReceiverAssembly="Amende.SharePoint.Branding, Version=1.0.0.0, Culture=neutral, PublicKeyToken=e39ad163a2911e63"
ReceiverClass="Amende.SharePoint.Branding.FeatureReceivers.DesignActivatorFeatureReceiver"
>
</Feature>
This refferences an assembly where we can find the DesignActivatorFeatureReceiver, to find the ReceiverAssemply and the ReceiverClass I usually use Lutz's Roeders .Net Reflector. Excellent tool!
I will post the code for the feature receiver in a couple of days.
The master page stapler feature
This feature makes shure that all new sites created in the farm get the custom master page attached. It consists of two files; the feature.xml which indicates this is a farm feature, and an elements.xml describing what site templates are affected by this feature. In our case this is all of them. We therefor use the term "Global". For som strange reason the global term do not include the team site site template. We therefore have to refference this seperately using the STS#1 definition name.
Heres the elements.xml:
<?xml version="1.0" encoding="utf-8" ?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/" >
<FeatureSiteTemplateAssociation Id="1D8E532B-C354-43f0-89FF-10401F3C70CD" TemplateName="GLOBAL" />
<FeatureSiteTemplateAssociation Id="1D8E532B-C354-43f0-89FF-10401F3C70CD" TemplateName="STS#1" />
</Elements>
And here is the feature.xml file:
<?xml version="1.0" encoding="utf-8" ?>
<Feature Id="B7685480-E85D-4cb0-A100-FB470DDE1768"
Title="ActivateDesign Feature Stapler"
Description="Staples the Master Page Activator feature to all Site Definitions (GLOBAL and SPS#1)"
Version="1.0.0.0"
Scope="Farm"
Hidden="FALSE"
xmlns="http://schemas.microsoft.com/sharepoint/"
>
<ElementManifests>
<ElementManifest Location="elements.xml"/>
</ElementManifests>
</Feature>
Again, please remember to change the GUID of the feature.
Deploying the features
I am still using the old school way to deploy these features using stsadm commands installing and activating the features. First I deploy the master page adder and test this by checking that all of the files are where they are supposed to be. I also change the masterpage manually to check that everything looks ok.
Secondly I switch back to the SharePoint default master and deploy the switcher feature. I test this by activating the feature on a number of sites.
At last I install and activate the farm feature and test this by creating a new site.