In Foundation, it is not possible to change the masterpage for a site using SPD or the UI. You need to do this through code. I usually do this by creating a feature that has 2 properties, oldmaster and newmaster. On Activation, i swap out new for old in the 2 properties SPDoctor mentions, and on deactivate i reverse that action. Here's the code for my Branding feature, that allow you to set a masterpage, a site logo and an alternate CSS file:
using System;
using System.Security.Permissions;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Security;
namespace DCubed.Framework.Library.FeatureReceivers
{
/// <summary>
/// Represents the feature receiver van de MasterPage Configuration Feature
/// </summary>
[CLSCompliant(false)]
public class BrandingConfigurationReceiver : SPFeatureReceiver
{
/// <summary>
/// Represents the property name of feature
/// </summary>
public const string MasterPageProperty = "MasterPage";
/// <summary>
/// Represents the property name of feature
/// </summary>
public const string CssFileProperty = "CssFile";
/// <summary>
/// Represents the property name of feature
/// </summary>
public const string LogoFileProperty = "LogoFile";
/// <summary>
/// Represents the property name of feature
/// </summary>
public const string DefaultMasterPageProperty = "DefaultMasterPage";
/// <summary>
/// Occurs after a Feature is activated.
/// </summary>
/// <param name="properties">An <see cref="T:Microsoft.SharePoint.SPFeatureReceiverProperties"></see> object that represents the properties of the event.</param>
[SharePointPermission(SecurityAction.LinkDemand, ObjectModel = true)]
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
if (properties == null)
{
throw new ArgumentNullException("properties");
}
var web = (SPWeb)properties.Feature.Parent;
var newMaster = properties.Feature.Properties[MasterPageProperty];
var oldMaster = properties.Feature.Properties[DefaultMasterPageProperty];
if (oldMaster != null)
{
if (newMaster != null)
{
if (web.CustomMasterUrl.Contains(oldMaster.Value))
{
web.CustomMasterUrl = web.CustomMasterUrl.Replace(oldMaster.Value, newMaster.Value);
}
if (web.MasterUrl.Contains(oldMaster.Value))
{
web.MasterUrl = web.MasterUrl.Replace(oldMaster.Value, newMaster.Value);
}
}
}
var cssFile = properties.Feature.Properties[CssFileProperty];
if (cssFile != null)
{
// assuming the css file is deployed in the Style Library
web.AlternateCssUrl = ResourceHelper.GetValue("stylelibraryList", "core", web.Locale.LCID) + "/css/" + cssFile.Value;
}
var logoFile = properties.Feature.Properties[LogoFileProperty];
if (logoFile != null)
{
// assuming the logofile is deployed in the Style Library
web.SiteLogoUrl = "~/" + ResourceHelper.GetValue("stylelibraryList", "core", web.Locale.LCID) + "/gfx/" + logoFile.Value;
}
web.Update();
}
// rest omitted for brevity...
}
}
ResourceHelper is a custom class that wraps SPUtility.GetLocalizedString. The main method looks like this:
/// <summary>
/// Get and returns the value from the Resource Files
/// </summary>
/// <param name="key">Identifier to look for in the Resource Files</param>
/// <param name="file">The resourcefile to look in</param>
/// <param name="localeId">The Locale LCID of the desired language</param>
/// <returns>The value returned from the Resource File or Not Found message</returns>
public static string GetValue(string key, string file, int localeId)
{
var retVal = SPUtility.GetLocalizedString(String.Format(CultureInfo.InvariantCulture, "$Resources:{0}", key), file, (uint)localeId);
return retVal;
}