Wednesday, July 9, 2008

SP2007: Custom Master Pages on Subsites

While MOSS contains an interface which should allow you to set the master page for all sites, this does not work in practice. Instead you can receive the message "The site master page setting currently applied to this site is invalid. Please select a new master page and apply it"
http://support.microsoft.com/kb/936908

To make this work, Microsoft suggests using a Feature to activate the publishing feature on all sites.
You don't have to turn on publishing for all subsites. Instead you can use a Feature to apply this master page to the appropriate sites.


To automatically apply the master page to the site it is helpful if you understand what Features are, and the Staplee and Stapler setup for applying Features.
http://msdn.microsoft.com/en-us/library/ms460318.aspx

In the Features folder, create 2 new folders
SubsiteStapler
SubsiteStaplee

SubsiteStapler
In the SubsiteStapler folder you'll have a feature.xml file and an element.xml file.

The feature.xml file sets up the feature. Note that ID is a unique guid. If you need this on several servers on the same farm you'll likely need different guids.

<Feature
Id="130ed937-2658-445e-9df3-34f40b9d702c"
Title="Subsite Creation Feature Stapler"
Scope="Farm"
xmlns="http://schemas.microsoft.com/sharepoint/" >
<ElementManifests>
<ElementManifest Location="elements.xml" />
</ElementManifests>
</Feature>

The elements.xml file tells MOSS what templates you are going to apply this feature to. Note that the ID listed on all of these lines is the same ID from the feature.xml file in the SubsiteStaplee Feature below. Basically you are using the Stapler feature to associate the Staplee feature with all of the templates listed. You can also add other templates (like your own custom ones)

<Elements xmlns="http://schemas.microsoft.com/sharepoint/" >
<FeatureSiteTemplateAssociation Id="bb77f112-2cda-4e92-b0ff-820c0216a7fe" TemplateName="STS#0"/>
<FeatureSiteTemplateAssociation Id="bb77f112-2cda-4e92-b0ff-820c0216a7fe" TemplateName="STS#1"/>
<FeatureSiteTemplateAssociation Id="bb77f112-2cda-4e92-b0ff-820c0216a7fe" TemplateName="STS#2"/>

<FeatureSiteTemplateAssociation Id="bb77f112-2cda-4e92-b0ff-820c0216a7fe" TemplateName="MPS#0"/>
<FeatureSiteTemplateAssociation Id="bb77f112-2cda-4e92-b0ff-820c0216a7fe" TemplateName="MPS#1"/>
<FeatureSiteTemplateAssociation Id="bb77f112-2cda-4e92-b0ff-820c0216a7fe" TemplateName="MPS#2"/>
<FeatureSiteTemplateAssociation Id="bb77f112-2cda-4e92-b0ff-820c0216a7fe" TemplateName="MPS#3"/>
<FeatureSiteTemplateAssociation Id="bb77f112-2cda-4e92-b0ff-820c0216a7fe" TemplateName="MPS#4"/>

<FeatureSiteTemplateAssociation Id="bb77f112-2cda-4e92-b0ff-820c0216a7fe" TemplateName="WIKI#0"/>

<FeatureSiteTemplateAssociation Id="bb77f112-2cda-4e92-b0ff-820c0216a7fe" TemplateName="BLOG#0"/>
</Elements>

SubsiteStaplee
In the SubsiteStaplee folder you'll need your master page (subsite.master) and a feature.xml and element.xml files


feature.xml

<Feature
Id="bb77f112-2cda-4e92-b0ff-820c0216a7fe"
Title="Subsite Creation Feature"
Scope="Web"
ReceiverAssembly="MySiteCreate, Version=1.0.0.0, Culture=neutral, PublicKeyToken=c726fa831b98198d"
ReceiverClass="Microsoft.IW.MySiteCreate"
Hidden="TRUE"
xmlns="http://schemas.microsoft.com/sharepoint/">

<ElementManifests>
<ElementFile Location="subsite.master"/>
<ElementManifest Location="element.xml"/>
</ElementManifests>
<Properties>
<Property Key="MasterName" Value="subsite.master"/>
<Property Key="CSSName" Value="/Style Library/customcss.css"/>
</Properties>
</Feature>


elements.xml

<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<Module Name="SubsiteStapleeFiles" List="116" Url="_catalogs/masterpage">
<File Url="subsite.master" Type="GhostableInLibrary" />
</Module>
</Elements>

You should also notice the CSSName Property Key in feature.xml, which in this case is set to a custom sytle sheet in the Style Library. Change this to point to your style sheet and you can apply a style sheet at the same time you apply a master page.

MySiteCreate.dll
You'll aslo need the application which staples the subsite.master to the templates. You can use the MySiteCreate.dll found in the MySiteCreate kit, which you may have already installed if you are using a custom master page on your My Sites. It was designed to staple a master page to a My Site, but can be used to staple a master page to any site.
http://www.codeplex.com/CKS/Release/ProjectReleases.aspx?ReleaseId=2824
Drop it in /Windows/Assembly.

Finally register the features in a Command Prompt window:

first change directory to where your stsadm.exe program is, then run the commands:

stsadm -o installfeature -name SubsiteStaplee
stsadm -o activatefeature -name SubsiteStaplee -url http://yoursite
stsadm -o installfeature -name SubsiteStapler

iisreset

Now whenever a new Subsite is created, the SubsiteStapler Feature will kick off the SubsiteStaplee Feature which uses the MySiteCreate.dll to apply the subsite.master Master Page to the subsite.