- Change the master page and stylesheet settings for a site
- Staple the first feature to all site templates, so it is activated upon site creation
- Becky Bertram - blog - Applying a SharePoint Custom Master page Globally
- Jim Yang - blog - MOSS 2007 and WSS 3.0 Master Page
- Paul Papanek Stork - blog - Feature to Install a Custom Master Page
Brief rundown of SharePoint Object Model:
- SPSite is a Site Collection
- SPWeb is a Site within a Site Collection
- [web_object].MasterUrl
- [web_object].CustomMasterUrl
- [web_object].AlternateCssUrl
Note: all of the following is done within the FeatureActivated function of a custom class inheriting from the SPFeatureReceiver class. Now let's dive into some code (these are all different methods I tried to no avail)
- Created some variables and hard coded the locations within the feature:
string MasterUrl = "/_layouts/custom.master";
string CustomMasterUrl = "/_layouts/custom.master";
string AlternateCssUrl = "/StyleLibrary/Custom/CSS/stylesheet.css";
SPWeb web = (SPWeb)properties.Feature.Parent;
try {
web.MasterUrl = MasterUrl;
web.CustomMasterUrl = CustomMasterUrl;
web.AlternateCssUrl = AlternateCssUrl;
web.Update();
}
catch { } - Set the values of the current site to the values from the root site:
SPWeb web = (SPWeb)properties.Feature.Parent;
try {
web.MasterUrl = web.Site.RootWeb.MasterUrl;
web.CustomMasterUrl = web.Site.RootWeb.CustomMasterUrl;
web.AlternateCssUrl = web.Site.RootWeb.AlternateCssUrl;
web.Update();
}
catch { } - Set the values of the current site to the values from it's parent site:
SPWeb web = (SPWeb)properties.Feature.Parent;
try {
web.MasterUrl = web.ParentWeb.MasterUrl;
web.CustomMasterUrl = web.ParentWeb.CustomMasterUrl;
web.AlternateCssUrl = web.ParentWeb.AlternateCssUrl;
web.Update();
}
catch { }
I decided to take this to the Content Database for the portal in which I was working. Looking in the dbo.Webs table, I found that if the "Inherit" radio button is selected, there are still values in the DB for AlternateCssUrl, MasterUrl, and CustomMasterUrl. Running the above code, would put the same values in these fields, but the "Inherit" radio button would not be selected. I then performed the following steps:
- Copy a row (one site) from the database to a text file
- Change each of the 3 settings (Site Master, System Master, and Alternate CSS) from "Inherit" to "Specify a ..."
- Copy the same row from the database to the second row of the text file
- Change each of the 3 settings back to "Inherit"
- Copy the same row from the database to the third row of the text file
- Change each of the 3 settings back to "Specify a ..."
- Copy the same row from the database to the fourth row of the text file
- "Inherit": 547275
- "Specify a ...": 46616C73
- SPWeb.Properties (C# type SPPropertyBag)
- vti_extenderversion: 12.0.0.4518
- vti_associatevisitorgroup: 4
- vti_defaultlanguage: en-us
- vti_associategroups: 5;4;3;6;7;8;9;10;11;14;15;17;18;28
- vti_associateownergroup: 3
- vti_associatemembergroup: 5
- SPWeb.AllProperties (C# type Hashtable)
- vti_extenderversion: 12.0.0.4518
- __InheritsCustomMasterUrl: False
- vti_associatevisitorgroup: 4
- vti_categories: Business Competition Expense\ Report Goals/Objectives Ideas In\ Process Miscellaneous Planning Schedule Travel VIP Waiting
- vti_associatemembergroup: 5
- vti_defaultlanguage: en-us
- vti_associateownergroup: 3
- vti_associategroups: 5;4;3;6;7;8;9;10;11;14;15;17;18;28
- __InheritsAlternateCssUrl: False
- vti_approvallevels: Approved Rejected Pending\ Review
- __InheritsMasterUrl: False
I simply set these values to "True" (note, that is a string of "True" and not a 1 or C# true), which resulted in this:
However, it did not pull the correct values to begin with. Therefore, it would appear that SharePoint uses these settings for when the parent's master pages/css are changed, and not relying on these settings for everytime the site is accessed.
All in all, here is the final code I came up with for my Feature (inside FeatureActivated function):
SPWeb web = (SPWeb)properties.Feature.Parent;
Hashtable hash = web.AllProperties;
try {
web.MasterUrl = web.ParentWeb.MasterUrl;
hash["__InheritsMasterUrl"] = "True";
web.Update();
}
catch { }
try {
web.CustomMasterUrl = web.ParentWeb.CustomMasterUrl;
hash["__InheritsCustomMasterUrl"] = "True";
web.Update();
}
catch { }
try {
web.AlternateCssUrl = web.ParentWeb.AlternateCssUrl;
hash["__InheritsAlternateCssUrl"] = "True";
web.Update();
}
catch { }
I hope this helps you, as I know I was pulling my hair out for a long time over this.
Enjoy!
--andrew
Correction [06.11.2008]: I just realized that in my final code, I had the following line:
web.MasterUrl = web.ParentWeb.CustomMasterUrl;
This works just fine, except I am pulling the wrong master page setting from the parent site for the current setting. This should read:
web.MasterUrl = web.ParentWeb.MasterUrl;
I have corrected this above in the code.