I have created a custom MasterPage and added a feature event receiver to deploy it to my farm to be able to enable it using PowerShell.
I have followed this excellent blog post on how to create the feature in Visual Studio and everything work's perfect.
How to deploy a custom MasterPage in SharePoint 2013 using Visual Studio
However, when i tried to enable the feature in my test environment to a Site where publishing infrastructure already were published, i received this error several times on the application servers logs.
Event log message was: 'Failed to create the 'Images' library.'. Exception was: 'Microsoft.SharePoint.SPException: The feature failed to activate because a list at 'PublishingImages' already exists in this site. Delete or rename the list and try activating the feature again. at Microsoft.SharePoint.Publishing.Internal.ProvisioningHelper.AddList(SPListCollection lists, String urlName, String title, String description, Guid featureId, Guid[] previousVersionFeatureIds, Int32 templateType, Boolean& newListCreated) at Microsoft.SharePoint.Publishing.Internal.ProvisioningHelper.AddList(SPListCollection lists, String urlName, String title, String description, Guid featureId, Guid[] previousVersionFeatureIds, PublishingTemplateType templateType, Boolean& newListCreated) at Microsoft.SharePoint.Publishing.Internal.AreaProvisioner.CreateImagesLibrary(SPList approvalTaskList)'
It's kinda obvious that there were some problems as the publishing feature were already enabled and the "Images" (publishingimages) library were already in place. I would like to avoid this error when i'm ready to deploy the solution in our production environment.
From the blog post i mentioned earlier, this is a piece of the code for the event receiver:
string webAppRelativePath = topLevelSite.ServerRelativeUrl;
if (!webAppRelativePath.EndsWith("/"))
{
webAppRelativePath += "/";
}
// Activate publishing infrastructure
site.Features.Add(new Guid("f6924d36-2fa8-4f0b-b16d-06b7250180fa"), true);
// Enumerate through each site and apply branding.
foreach (SPWeb web in site.AllWebs)
{
// Activate the publishing feature for all webs.
web.Features.Add(new Guid("94c94ca6-b32f-4da9-a9e3-1f3d343d7ecb"), true);
web.MasterUrl = webAppRelativePath + "_catalogs/masterpage/MyCustom.master";
web.CustomMasterUrl = webAppRelativePath + "_catalogs/masterpage/MyCustom.master";
web.Update();
}
It's missing to check if the Publishing Infrastructure feature already are enabled. My server-side coding skills are kind of rusty, but i'm thinking to check if the site feature is added and then check for each web if the feature is enabled.
Am i on the right track code-wise?
Guid siteguid= new Guid("f6924d36-2fa8-4f0b-b16d-06b7250180fa");
Guid webguid = new Guid("94c94ca6-b32f-4da9-a9e3-1f3d343d7ecb");
// Check if the Publishing infrastructure feature is enabled
if ((site.Features[siteguid] == null)) {
// Activate publishing infrastructure
site.Features.Add(new Guid("f6924d36-2fa8-4f0b-b16d-06b7250180fa"), true);
}
// Enumerate through each site and apply branding.
foreach (SPWeb web in site.AllWebs)
{
// Check if the Publishing feature is enabled
if (web.Features[webguid] == null){
// Activate the publishing feature for all webs.
web.Features.Add(new Guid("94c94ca6-b32f-4da9-a9e3-1f3d343d7ecb"), true);
}
web.MasterUrl = webAppRelativePath + "_catalogs/masterpage/MyCustom.master";
web.CustomMasterUrl = webAppRelativePath + "_catalogs/masterpage/MyCustom.master";
web.Update();
}